CS5500-Final Project-Valgrind Warriors
nuklear.h
Go to the documentation of this file.
1 /*
215 */
216 #ifndef NK_SINGLE_FILE
217  #define NK_SINGLE_FILE
218 #endif
219 
220 #ifndef NK_NUKLEAR_H_
221 #define NK_NUKLEAR_H_
222 
223 #ifdef __cplusplus
224 extern "C" {
225 #endif
226 /*
227  * ==============================================================
228  *
229  * CONSTANTS
230  *
231  * ===============================================================
232  */
233 #define NK_UNDEFINED (-1.0f)
234 #define NK_UTF_INVALID 0xFFFD /* internal invalid utf8 rune */
235 #define NK_UTF_SIZE 4 /* describes the number of bytes a glyph consists of*/
236 #ifndef NK_INPUT_MAX
237  #define NK_INPUT_MAX 16
238 #endif
239 #ifndef NK_MAX_NUMBER_BUFFER
240  #define NK_MAX_NUMBER_BUFFER 64
241 #endif
242 #ifndef NK_SCROLLBAR_HIDING_TIMEOUT
243  #define NK_SCROLLBAR_HIDING_TIMEOUT 4.0f
244 #endif
245 /*
246  * ==============================================================
247  *
248  * HELPER
249  *
250  * ===============================================================
251  */
252 #ifndef NK_API
253  #ifdef NK_PRIVATE
254  #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199409L))
255  #define NK_API static inline
256  #elif defined(__cplusplus)
257  #define NK_API static inline
258  #else
259  #define NK_API static
260  #endif
261  #else
262  #define NK_API extern
263  #endif
264 #endif
265 #ifndef NK_LIB
266  #ifdef NK_SINGLE_FILE
267  #define NK_LIB static
268  #else
269  #define NK_LIB extern
270  #endif
271 #endif
272 
273 #define NK_INTERN static
274 #define NK_STORAGE static
275 #define NK_GLOBAL static
276 
277 #define NK_FLAG(x) (1 << (x))
278 #define NK_STRINGIFY(x) #x
279 #define NK_MACRO_STRINGIFY(x) NK_STRINGIFY(x)
280 #define NK_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1 ## arg2
281 #define NK_STRING_JOIN_DELAY(arg1, arg2) NK_STRING_JOIN_IMMEDIATE(arg1, arg2)
282 #define NK_STRING_JOIN(arg1, arg2) NK_STRING_JOIN_DELAY(arg1, arg2)
283 
284 #ifdef _MSC_VER
285  #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__COUNTER__)
286 #else
287  #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__LINE__)
288 #endif
289 
290 #ifndef NK_STATIC_ASSERT
291 #define NK_STATIC_ASSERT(exp) typedef char NK_UNIQUE_NAME(_dummy_array)[(exp)?1:-1]
292 #endif
293 
294 #ifndef NK_FILE_LINE
295 #ifdef _MSC_VER
296  #define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__COUNTER__)
297 #else
298  #define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__LINE__)
299 #endif
300 #endif
301 
302 #define NK_MIN(a,b) ((a) < (b) ? (a) : (b))
303 #define NK_MAX(a,b) ((a) < (b) ? (b) : (a))
304 #define NK_CLAMP(i,v,x) (NK_MAX(NK_MIN(v,x), i))
305 
306 #ifdef NK_INCLUDE_STANDARD_VARARGS
307  #if defined(_MSC_VER) && (_MSC_VER >= 1600) /* VS 2010 and above */
308  #include <sal.h>
309  #define NK_PRINTF_FORMAT_STRING _Printf_format_string_
310  #else
311  #define NK_PRINTF_FORMAT_STRING
312  #endif
313  #if defined(__GNUC__)
314  #define NK_PRINTF_VARARG_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, fmtargnumber+1)))
315  #define NK_PRINTF_VALIST_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, 0)))
316  #else
317  #define NK_PRINTF_VARARG_FUNC(fmtargnumber)
318  #define NK_PRINTF_VALIST_FUNC(fmtargnumber)
319  #endif
320 #endif
321 
322 /*
323  * ===============================================================
324  *
325  * BASIC
326  *
327  * ===============================================================
328  */
329 #ifdef NK_INCLUDE_FIXED_TYPES
330  #include <stdint.h>
331 #include <cstdint>
332  #define NK_INT8 int8_t
333  #define NK_UINT8 uint8_t
334  #define NK_INT16 int16_t
335  #define NK_UINT16 uint16_t
336  #define NK_INT32 int32_t
337  #define NK_UINT32 uint32_t
338  #define NK_SIZE_TYPE uintptr_t
339  #define NK_POINTER_TYPE uintptr_t
340 #else
341  #ifndef NK_INT8
342  #define NK_INT8 signed char
343  #endif
344  #ifndef NK_UINT8
345  #define NK_UINT8 unsigned char
346  #endif
347  #ifndef NK_INT16
348  #define NK_INT16 signed short
349  #endif
350  #ifndef NK_UINT16
351  #define NK_UINT16 unsigned short
352  #endif
353  #ifndef NK_INT32
354  #if defined(_MSC_VER)
355  #define NK_INT32 __int32
356  #else
357  #define NK_INT32 signed int
358  #endif
359  #endif
360  #ifndef NK_UINT32
361  #if defined(_MSC_VER)
362  #define NK_UINT32 unsigned __int32
363  #else
364  #define NK_UINT32 unsigned int
365  #endif
366  #endif
367  #ifndef NK_SIZE_TYPE
368  #if defined(_WIN64) && defined(_MSC_VER)
369  #define NK_SIZE_TYPE unsigned __int64
370  #elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
371  #define NK_SIZE_TYPE unsigned __int32
372  #elif defined(__GNUC__) || defined(__clang__)
373  #if defined(__x86_64__) || defined(__ppc64__)
374  #define NK_SIZE_TYPE unsigned long
375  #else
376  #define NK_SIZE_TYPE unsigned int
377  #endif
378  #else
379  #define NK_SIZE_TYPE unsigned long
380  #endif
381  #endif
382  #ifndef NK_POINTER_TYPE
383  #if defined(_WIN64) && defined(_MSC_VER)
384  #define NK_POINTER_TYPE unsigned __int64
385  #elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
386  #define NK_POINTER_TYPE unsigned __int32
387  #elif defined(__GNUC__) || defined(__clang__)
388  #if defined(__x86_64__) || defined(__ppc64__)
389  #define NK_POINTER_TYPE unsigned long
390  #else
391  #define NK_POINTER_TYPE unsigned int
392  #endif
393  #else
394  #define NK_POINTER_TYPE unsigned long
395  #endif
396  #endif
397 #endif
398 
399 typedef NK_INT8 nk_char;
404 typedef NK_INT32 nk_int;
408 
409 typedef nk_uint nk_hash;
411 typedef nk_uint nk_rune;
412 
413 /* Make sure correct type size:
414  * This will fire with a negative subscript error if the type sizes
415  * are set incorrectly by the compiler, and compile out if not */
418 NK_STATIC_ASSERT(sizeof(nk_uint) == 4);
419 NK_STATIC_ASSERT(sizeof(nk_int) == 4);
420 NK_STATIC_ASSERT(sizeof(nk_byte) == 1);
422 NK_STATIC_ASSERT(sizeof(nk_rune) >= 4);
423 NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void*));
424 NK_STATIC_ASSERT(sizeof(nk_ptr) >= sizeof(void*));
425 
426 /* ============================================================================
427  *
428  * API
429  *
430  * =========================================================================== */
431 struct nk_buffer;
432 struct nk_allocator;
433 struct nk_command_buffer;
434 struct nk_draw_command;
435 struct nk_convert_config;
436 struct nk_style_item;
437 struct nk_text_edit;
438 struct nk_draw_list;
439 struct nk_user_font;
440 struct nk_panel;
441 struct nk_context;
442 struct nk_draw_vertex_layout_element;
443 struct nk_style_button;
444 struct nk_style_toggle;
445 struct nk_style_selectable;
446 struct nk_style_slide;
447 struct nk_style_progress;
448 struct nk_style_scrollbar;
449 struct nk_style_edit;
450 struct nk_style_property;
451 struct nk_style_chart;
452 struct nk_style_combo;
453 struct nk_style_tab;
455 struct nk_style_window;
456 
458 struct nk_color {nk_byte r,g,b,a;};
459 struct nk_colorf {float r,g,b,a;};
460 struct nk_vec2 {float x,y;};
461 struct nk_vec2i {short x, y;};
462 struct nk_rect {float x,y,w,h;};
463 struct nk_recti {short x,y,w,h;};
464 typedef char nk_glyph[NK_UTF_SIZE];
465 typedef union {void *ptr; int id;} nk_handle;
466 struct nk_image {nk_handle handle;unsigned short w,h;unsigned short region[4];};
467 struct nk_cursor {struct nk_image img; struct nk_vec2 size, offset;};
468 struct nk_scroll {nk_uint x, y;};
469 
482 
483 typedef void*(*nk_plugin_alloc)(nk_handle, void *old, nk_size);
484 typedef void (*nk_plugin_free)(nk_handle, void *old);
485 typedef int(*nk_plugin_filter)(const struct nk_text_edit*, nk_rune unicode);
486 typedef void(*nk_plugin_paste)(nk_handle, struct nk_text_edit*);
487 typedef void(*nk_plugin_copy)(nk_handle, const char*, int len);
488 
489 struct nk_allocator {
493 };
509 };
510 /* =============================================================================
511  *
512  * CONTEXT
513  *
514  * =============================================================================*/
515 /*/// ### Context
547  */
548 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
549 /*/// #### nk_init_default
564 */
565 NK_API int nk_init_default(struct nk_context*, const struct nk_user_font*);
566 #endif
567 /*/// #### nk_init_fixed
589 */
590 NK_API int nk_init_fixed(struct nk_context*, void *memory, nk_size size, const struct nk_user_font*);
591 /*/// #### nk_init
607 */
608 NK_API int nk_init(struct nk_context*, struct nk_allocator*, const struct nk_user_font*);
609 /*/// #### nk_init_custom
626 */
627 NK_API int nk_init_custom(struct nk_context*, struct nk_buffer *cmds, struct nk_buffer *pool, const struct nk_user_font*);
628 /*/// #### nk_clear
640 */
641 NK_API void nk_clear(struct nk_context*);
642 /*/// #### nk_free
653 */
654 NK_API void nk_free(struct nk_context*);
655 #ifdef NK_INCLUDE_COMMAND_USERDATA
656 /*/// #### nk_set_user_data
667 */
668 NK_API void nk_set_user_data(struct nk_context*, nk_handle handle);
669 #endif
670 /* =============================================================================
671  *
672  * INPUT
673  *
674  * =============================================================================*/
675 /*/// ### Input
735 */
736 enum nk_keys {
751  /* Shortcuts: text field */
764  /* Shortcuts: scrollbar */
769  NK_KEY_MAX
770 };
777 };
778 /*/// #### nk_input_begin
789 */
791 /*/// #### nk_input_motion
803 */
804 NK_API void nk_input_motion(struct nk_context*, int x, int y);
805 /*/// #### nk_input_key
817 */
818 NK_API void nk_input_key(struct nk_context*, enum nk_keys, int down);
819 /*/// #### nk_input_button
833 */
834 NK_API void nk_input_button(struct nk_context*, enum nk_buttons, int x, int y, int down);
835 /*/// #### nk_input_scroll
848 */
849 NK_API void nk_input_scroll(struct nk_context*, struct nk_vec2 val);
850 /*/// #### nk_input_char
866 */
867 NK_API void nk_input_char(struct nk_context*, char);
868 /*/// #### nk_input_glyph
883 */
885 /*/// #### nk_input_unicode
899 */
901 /*/// #### nk_input_end
912 */
914 /* =============================================================================
915  *
916  * DRAWING
917  *
918  * =============================================================================*/
919 /*/// ### Drawing
1142 */
1150 };
1152  nk_handle texture; /* texture handle to a texture with a white pixel */
1153  struct nk_vec2 uv; /* coordinates to a white pixel in the texture */
1154 };
1156  float global_alpha; /* global alpha value */
1157  enum nk_anti_aliasing line_AA; /* line anti-aliasing flag can be turned off if you are tight on memory */
1158  enum nk_anti_aliasing shape_AA; /* shape anti-aliasing flag can be turned off if you are tight on memory */
1159  unsigned circle_segment_count; /* number of segments used for circles: default to 22 */
1160  unsigned arc_segment_count; /* number of segments used for arcs: default to 22 */
1161  unsigned curve_segment_count; /* number of segments used for curves: default to 22 */
1162  struct nk_draw_null_texture null; /* handle to texture with a white pixel for shape drawing */
1163  const struct nk_draw_vertex_layout_element *vertex_layout; /* describes the vertex output format and packing */
1164  nk_size vertex_size; /* sizeof one vertex for vertex packing */
1165  nk_size vertex_alignment; /* vertex alignment: Can be obtained by NK_ALIGNOF */
1166 };
1167 /*/// #### nk__begin
1180 */
1181 NK_API const struct nk_command* nk__begin(struct nk_context*);
1182 /*/// #### nk__next
1195 */
1196 NK_API const struct nk_command* nk__next(struct nk_context*, const struct nk_command*);
1197 /*/// #### nk_foreach
1210 */
1211 #define nk_foreach(c, ctx) for((c) = nk__begin(ctx); (c) != 0; (c) = nk__next(ctx,c))
1212 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
1213 /*/// #### nk_convert
1241 */
1242 NK_API nk_flags nk_convert(struct nk_context*, struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements, const struct nk_convert_config*);
1243 /*/// #### nk__draw_begin
1256 */
1257 NK_API const struct nk_draw_command* nk__draw_begin(const struct nk_context*, const struct nk_buffer*);
1258 /*/// #### nk__draw_end
1271 */
1272 NK_API const struct nk_draw_command* nk__draw_end(const struct nk_context*, const struct nk_buffer*);
1273 /*/// #### nk__draw_next
1287 */
1288 NK_API const struct nk_draw_command* nk__draw_next(const struct nk_draw_command*, const struct nk_buffer*, const struct nk_context*);
1289 /*/// #### nk_draw_foreach
1301 */
1302 #define nk_draw_foreach(cmd,ctx, b) for((cmd)=nk__draw_begin(ctx, b); (cmd)!=0; (cmd)=nk__draw_next(cmd, b, ctx))
1303 #endif
1304 /* =============================================================================
1305  *
1306  * WINDOW
1307  *
1308  * =============================================================================
1393 //
1415 //
1421 //
1427 */
1428 /*
1450 */
1463 };
1464 /*/// #### nk_begin
1481 */
1482 NK_API int nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags);
1483 /*/// #### nk_begin_titled
1501 */
1502 NK_API int nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, struct nk_rect bounds, nk_flags flags);
1503 /*/// #### nk_end
1514 */
1515 NK_API void nk_end(struct nk_context *ctx);
1516 /*/// #### nk_window_find
1530 */
1531 NK_API struct nk_window *nk_window_find(struct nk_context *ctx, const char *name);
1532 /*/// #### nk_window_get_bounds
1546 */
1548 /*/// #### nk_window_get_position
1562 */
1564 /*/// #### nk_window_get_size
1578 */
1580 /*/// #### nk_window_get_width
1594 */
1596 /*/// #### nk_window_get_height
1610 */
1612 /*/// #### nk_window_get_panel
1628 */
1630 /*/// #### nk_window_get_content_region
1647 */
1649 /*/// #### nk_window_get_content_region_min
1666 */
1668 /*/// #### nk_window_get_content_region_max
1685 */
1687 /*/// #### nk_window_get_content_region_size
1703 */
1705 /*/// #### nk_window_get_canvas
1722 */
1724 /*/// #### nk_window_get_scroll
1738 */
1739 NK_API void nk_window_get_scroll(struct nk_context*, nk_uint *offset_x, nk_uint *offset_y);
1740 /*/// #### nk_window_has_focus
1753 */
1755 /*/// #### nk_window_is_hovered
1768 */
1770 /*/// #### nk_window_is_collapsed
1783 */
1784 NK_API int nk_window_is_collapsed(struct nk_context *ctx, const char *name);
1785 /*/// #### nk_window_is_closed
1797 */
1798 NK_API int nk_window_is_closed(struct nk_context*, const char*);
1799 /*/// #### nk_window_is_hidden
1811 */
1812 NK_API int nk_window_is_hidden(struct nk_context*, const char*);
1813 /*/// #### nk_window_is_active
1825 */
1826 NK_API int nk_window_is_active(struct nk_context*, const char*);
1827 /*/// #### nk_window_is_any_hovered
1838 */
1840 /*/// #### nk_item_is_any_active
1853 */
1855 /*/// #### nk_window_set_bounds
1866 */
1867 NK_API void nk_window_set_bounds(struct nk_context*, const char *name, struct nk_rect bounds);
1868 /*/// #### nk_window_set_position
1879 */
1880 NK_API void nk_window_set_position(struct nk_context*, const char *name, struct nk_vec2 pos);
1881 /*/// #### nk_window_set_size
1892 */
1893 NK_API void nk_window_set_size(struct nk_context*, const char *name, struct nk_vec2);
1894 /*/// #### nk_window_set_focus
1904 */
1905 NK_API void nk_window_set_focus(struct nk_context*, const char *name);
1906 /*/// #### nk_window_set_scroll
1920 */
1921 NK_API void nk_window_set_scroll(struct nk_context*, nk_uint offset_x, nk_uint offset_y);
1922 /*/// #### nk_window_close
1932 */
1933 NK_API void nk_window_close(struct nk_context *ctx, const char *name);
1934 /*/// #### nk_window_collapse
1945 */
1946 NK_API void nk_window_collapse(struct nk_context*, const char *name, enum nk_collapse_states state);
1947 /*/// #### nk_window_collapse_if
1959 */
1960 NK_API void nk_window_collapse_if(struct nk_context*, const char *name, enum nk_collapse_states, int cond);
1961 /*/// #### nk_window_show
1972 */
1973 NK_API void nk_window_show(struct nk_context*, const char *name, enum nk_show_states);
1974 /*/// #### nk_window_show_if
1986 */
1987 NK_API void nk_window_show_if(struct nk_context*, const char *name, enum nk_show_states, int cond);
1988 /* =============================================================================
1989  *
1990  * LAYOUT
1991  *
1992  * =============================================================================
2237 //
2244 //
2250 //
2254 //
2260 */
2261 /*/// #### nk_layout_set_min_row_height
2275 */
2276 NK_API void nk_layout_set_min_row_height(struct nk_context*, float height);
2277 /*/// #### nk_layout_reset_min_row_height
2286 */
2288 /*/// #### nk_layout_widget_bounds
2299 */
2301 /*/// #### nk_layout_ratio_from_pixel
2313 */
2314 NK_API float nk_layout_ratio_from_pixel(struct nk_context*, float pixel_width);
2315 /*/// #### nk_layout_row_dynamic
2328 */
2329 NK_API void nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols);
2330 /*/// #### nk_layout_row_static
2344 */
2345 NK_API void nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols);
2346 /*/// #### nk_layout_row_begin
2358 */
2359 NK_API void nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols);
2360 /*/// #### nk_layout_row_push
2370 */
2371 NK_API void nk_layout_row_push(struct nk_context*, float value);
2372 /*/// #### nk_layout_row_end
2381 */
2383 /*/// #### nk_layout_row
2395 */
2396 NK_API void nk_layout_row(struct nk_context*, enum nk_layout_format, float height, int cols, const float *ratio);
2397 /*/// #### nk_layout_row_template_begin
2407 */
2408 NK_API void nk_layout_row_template_begin(struct nk_context*, float row_height);
2409 /*/// #### nk_layout_row_template_push_dynamic
2419 */
2421 /*/// #### nk_layout_row_template_push_variable
2431 */
2433 /*/// #### nk_layout_row_template_push_static
2443 */
2445 /*/// #### nk_layout_row_template_end
2454 */
2456 /*/// #### nk_layout_space_begin
2468 */
2469 NK_API void nk_layout_space_begin(struct nk_context*, enum nk_layout_format, float height, int widget_count);
2470 /*/// #### nk_layout_space_push
2480 */
2481 NK_API void nk_layout_space_push(struct nk_context*, struct nk_rect bounds);
2482 /*/// #### nk_layout_space_end
2491 */
2493 /*/// #### nk_layout_space_bounds
2504 */
2506 /*/// #### nk_layout_space_to_screen
2518 */
2520 /*/// #### nk_layout_space_to_local
2532 */
2534 /*/// #### nk_layout_space_rect_to_screen
2546 */
2548 /*/// #### nk_layout_space_rect_to_local
2560 */
2562 /* =============================================================================
2563  *
2564  * GROUP
2565  *
2566  * =============================================================================
2649 */
2650 /*/// #### nk_group_begin
2663 */
2664 NK_API int nk_group_begin(struct nk_context*, const char *title, nk_flags);
2665 /*/// #### nk_group_begin_titled
2679 */
2680 NK_API int nk_group_begin_titled(struct nk_context*, const char *name, const char *title, nk_flags);
2681 /*/// #### nk_group_end
2690 */
2692 /*/// #### nk_group_scrolled_offset_begin
2708 */
2709 NK_API int nk_group_scrolled_offset_begin(struct nk_context*, nk_uint *x_offset, nk_uint *y_offset, const char *title, nk_flags flags);
2710 /*/// #### nk_group_scrolled_begin
2725 */
2726 NK_API int nk_group_scrolled_begin(struct nk_context*, struct nk_scroll *off, const char *title, nk_flags);
2727 /*/// #### nk_group_scrolled_end
2736 */
2738 /*/// #### nk_group_get_scroll
2750 */
2751 NK_API void nk_group_get_scroll(struct nk_context*, const char *id, nk_uint *x_offset, nk_uint *y_offset);
2752 /*/// #### nk_group_set_scroll
2764 */
2765 NK_API void nk_group_set_scroll(struct nk_context*, const char *id, nk_uint x_offset, nk_uint y_offset);
2766 /* =============================================================================
2767  *
2768  * TREE
2769  *
2770  * =============================================================================
2825 //
2835 */
2836 /*/// #### nk_tree_push
2856 */
2857 #define nk_tree_push(ctx, type, title, state) nk_tree_push_hashed(ctx, type, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
2858 /*/// #### nk_tree_push_id
2873 */
2874 #define nk_tree_push_id(ctx, type, title, state, id) nk_tree_push_hashed(ctx, type, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
2875 /*/// #### nk_tree_push_hashed
2893 */
2894 NK_API int nk_tree_push_hashed(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states initial_state, const char *hash, int len,int seed);
2895 /*/// #### nk_tree_image_push
2906 //
2916 */
2917 #define nk_tree_image_push(ctx, type, img, title, state) nk_tree_image_push_hashed(ctx, type, img, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
2918 /*/// #### nk_tree_image_push_id
2936 */
2937 #define nk_tree_image_push_id(ctx, type, img, title, state, id) nk_tree_image_push_hashed(ctx, type, img, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
2938 /*/// #### nk_tree_image_push_hashed
2957 */
2958 NK_API int nk_tree_image_push_hashed(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states initial_state, const char *hash, int len,int seed);
2959 /*/// #### nk_tree_pop
2968 */
2970 /*/// #### nk_tree_state_push
2984 */
2985 NK_API int nk_tree_state_push(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states *state);
2986 /*/// #### nk_tree_state_image_push
3001 */
3002 NK_API int nk_tree_state_image_push(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states *state);
3003 /*/// #### nk_tree_state_pop
3012 */
3014 
3015 #define nk_tree_element_push(ctx, type, title, state, sel) nk_tree_element_push_hashed(ctx, type, title, state, sel, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
3016 #define nk_tree_element_push_id(ctx, type, title, state, sel, id) nk_tree_element_push_hashed(ctx, type, title, state, sel, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
3017 NK_API int nk_tree_element_push_hashed(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states initial_state, int *selected, const char *hash, int len, int seed);
3018 NK_API int nk_tree_element_image_push_hashed(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states initial_state, int *selected, const char *hash, int len,int seed);
3020 
3021 /* =============================================================================
3022  *
3023  * LIST VIEW
3024  *
3025  * ============================================================================= */
3027 /* public: */
3028  int begin, end, count;
3029 /* private: */
3031  struct nk_context *ctx;
3034 };
3035 NK_API int nk_list_view_begin(struct nk_context*, struct nk_list_view *out, const char *id, nk_flags, int row_height, int row_count);
3037 /* =============================================================================
3038  *
3039  * WIDGET
3040  *
3041  * ============================================================================= */
3043  NK_WIDGET_INVALID, /* The widget cannot be seen and is completely out of view */
3044  NK_WIDGET_VALID, /* The widget is completely inside the window and can be updated and drawn */
3045  NK_WIDGET_ROM /* The widget is partially visible and cannot be updated */
3046 };
3049  NK_WIDGET_STATE_INACTIVE = NK_FLAG(2), /* widget is neither active nor hovered */
3050  NK_WIDGET_STATE_ENTERED = NK_FLAG(3), /* widget has been hovered on the current frame */
3051  NK_WIDGET_STATE_HOVER = NK_FLAG(4), /* widget is being hovered */
3052  NK_WIDGET_STATE_ACTIVED = NK_FLAG(5),/* widget is currently activated */
3053  NK_WIDGET_STATE_LEFT = NK_FLAG(6), /* widget is from this frame on not hovered anymore */
3055  NK_WIDGET_STATE_ACTIVE = NK_WIDGET_STATE_ACTIVED|NK_WIDGET_STATE_MODIFIED /* widget is currently activated */
3056 };
3067 NK_API void nk_spacing(struct nk_context*, int cols);
3068 /* =============================================================================
3069  *
3070  * TEXT
3071  *
3072  * ============================================================================= */
3079  NK_TEXT_ALIGN_BOTTOM = 0x20
3080 };
3085 };
3086 NK_API void nk_text(struct nk_context*, const char*, int, nk_flags);
3087 NK_API void nk_text_colored(struct nk_context*, const char*, int, nk_flags, struct nk_color);
3088 NK_API void nk_text_wrap(struct nk_context*, const char*, int);
3089 NK_API void nk_text_wrap_colored(struct nk_context*, const char*, int, struct nk_color);
3090 NK_API void nk_label(struct nk_context*, const char*, nk_flags align);
3091 NK_API void nk_label_colored(struct nk_context*, const char*, nk_flags align, struct nk_color);
3092 NK_API void nk_label_wrap(struct nk_context*, const char*);
3093 NK_API void nk_label_colored_wrap(struct nk_context*, const char*, struct nk_color);
3094 NK_API void nk_image(struct nk_context*, struct nk_image);
3095 NK_API void nk_image_color(struct nk_context*, struct nk_image, struct nk_color);
3096 #ifdef NK_INCLUDE_STANDARD_VARARGS
3097 NK_API void nk_labelf(struct nk_context*, nk_flags, NK_PRINTF_FORMAT_STRING const char*, ...) NK_PRINTF_VARARG_FUNC(3);
3098 NK_API void nk_labelf_colored(struct nk_context*, nk_flags, struct nk_color, NK_PRINTF_FORMAT_STRING const char*,...) NK_PRINTF_VARARG_FUNC(4);
3099 NK_API void nk_labelf_wrap(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*,...) NK_PRINTF_VARARG_FUNC(2);
3100 NK_API void nk_labelf_colored_wrap(struct nk_context*, struct nk_color, NK_PRINTF_FORMAT_STRING const char*,...) NK_PRINTF_VARARG_FUNC(3);
3101 NK_API void nk_labelfv(struct nk_context*, nk_flags, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(3);
3102 NK_API void nk_labelfv_colored(struct nk_context*, nk_flags, struct nk_color, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(4);
3103 NK_API void nk_labelfv_wrap(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(2);
3104 NK_API void nk_labelfv_colored_wrap(struct nk_context*, struct nk_color, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(3);
3105 NK_API void nk_value_bool(struct nk_context*, const char *prefix, int);
3106 NK_API void nk_value_int(struct nk_context*, const char *prefix, int);
3107 NK_API void nk_value_uint(struct nk_context*, const char *prefix, unsigned int);
3108 NK_API void nk_value_float(struct nk_context*, const char *prefix, float);
3109 NK_API void nk_value_color_byte(struct nk_context*, const char *prefix, struct nk_color);
3110 NK_API void nk_value_color_float(struct nk_context*, const char *prefix, struct nk_color);
3111 NK_API void nk_value_color_hex(struct nk_context*, const char *prefix, struct nk_color);
3112 #endif
3113 /* =============================================================================
3114  *
3115  * BUTTON
3116  *
3117  * ============================================================================= */
3118 NK_API int nk_button_text(struct nk_context*, const char *title, int len);
3119 NK_API int nk_button_label(struct nk_context*, const char *title);
3122 NK_API int nk_button_image(struct nk_context*, struct nk_image img);
3123 NK_API int nk_button_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags text_alignment);
3124 NK_API int nk_button_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
3125 NK_API int nk_button_image_label(struct nk_context*, struct nk_image img, const char*, nk_flags text_alignment);
3126 NK_API int nk_button_image_text(struct nk_context*, struct nk_image img, const char*, int, nk_flags alignment);
3127 NK_API int nk_button_text_styled(struct nk_context*, const struct nk_style_button*, const char *title, int len);
3128 NK_API int nk_button_label_styled(struct nk_context*, const struct nk_style_button*, const char *title);
3130 NK_API int nk_button_image_styled(struct nk_context*, const struct nk_style_button*, struct nk_image img);
3131 NK_API int nk_button_symbol_text_styled(struct nk_context*,const struct nk_style_button*, enum nk_symbol_type, const char*, int, nk_flags alignment);
3132 NK_API int nk_button_symbol_label_styled(struct nk_context *ctx, const struct nk_style_button *style, enum nk_symbol_type symbol, const char *title, nk_flags align);
3133 NK_API int nk_button_image_label_styled(struct nk_context*,const struct nk_style_button*, struct nk_image img, const char*, nk_flags text_alignment);
3134 NK_API int nk_button_image_text_styled(struct nk_context*,const struct nk_style_button*, struct nk_image img, const char*, int, nk_flags alignment);
3138 /* =============================================================================
3139  *
3140  * CHECKBOX
3141  *
3142  * ============================================================================= */
3143 NK_API int nk_check_label(struct nk_context*, const char*, int active);
3144 NK_API int nk_check_text(struct nk_context*, const char*, int,int active);
3145 NK_API unsigned nk_check_flags_label(struct nk_context*, const char*, unsigned int flags, unsigned int value);
3146 NK_API unsigned nk_check_flags_text(struct nk_context*, const char*, int, unsigned int flags, unsigned int value);
3147 NK_API int nk_checkbox_label(struct nk_context*, const char*, int *active);
3148 NK_API int nk_checkbox_text(struct nk_context*, const char*, int, int *active);
3149 NK_API int nk_checkbox_flags_label(struct nk_context*, const char*, unsigned int *flags, unsigned int value);
3150 NK_API int nk_checkbox_flags_text(struct nk_context*, const char*, int, unsigned int *flags, unsigned int value);
3151 /* =============================================================================
3152  *
3153  * RADIO BUTTON
3154  *
3155  * ============================================================================= */
3156 NK_API int nk_radio_label(struct nk_context*, const char*, int *active);
3157 NK_API int nk_radio_text(struct nk_context*, const char*, int, int *active);
3158 NK_API int nk_option_label(struct nk_context*, const char*, int active);
3159 NK_API int nk_option_text(struct nk_context*, const char*, int, int active);
3160 /* =============================================================================
3161  *
3162  * SELECTABLE
3163  *
3164  * ============================================================================= */
3165 NK_API int nk_selectable_label(struct nk_context*, const char*, nk_flags align, int *value);
3166 NK_API int nk_selectable_text(struct nk_context*, const char*, int, nk_flags align, int *value);
3167 NK_API int nk_selectable_image_label(struct nk_context*,struct nk_image, const char*, nk_flags align, int *value);
3168 NK_API int nk_selectable_image_text(struct nk_context*,struct nk_image, const char*, int, nk_flags align, int *value);
3169 NK_API int nk_selectable_symbol_label(struct nk_context*,enum nk_symbol_type, const char*, nk_flags align, int *value);
3170 NK_API int nk_selectable_symbol_text(struct nk_context*,enum nk_symbol_type, const char*, int, nk_flags align, int *value);
3171 
3172 NK_API int nk_select_label(struct nk_context*, const char*, nk_flags align, int value);
3173 NK_API int nk_select_text(struct nk_context*, const char*, int, nk_flags align, int value);
3174 NK_API int nk_select_image_label(struct nk_context*, struct nk_image,const char*, nk_flags align, int value);
3175 NK_API int nk_select_image_text(struct nk_context*, struct nk_image,const char*, int, nk_flags align, int value);
3176 NK_API int nk_select_symbol_label(struct nk_context*,enum nk_symbol_type, const char*, nk_flags align, int value);
3177 NK_API int nk_select_symbol_text(struct nk_context*,enum nk_symbol_type, const char*, int, nk_flags align, int value);
3178 
3179 /* =============================================================================
3180  *
3181  * SLIDER
3182  *
3183  * ============================================================================= */
3184 NK_API float nk_slide_float(struct nk_context*, float min, float val, float max, float step);
3185 NK_API int nk_slide_int(struct nk_context*, int min, int val, int max, int step);
3186 NK_API int nk_slider_float(struct nk_context*, float min, float *val, float max, float step);
3187 NK_API int nk_slider_int(struct nk_context*, int min, int *val, int max, int step);
3188 /* =============================================================================
3189  *
3190  * PROGRESSBAR
3191  *
3192  * ============================================================================= */
3193 NK_API int nk_progress(struct nk_context*, nk_size *cur, nk_size max, int modifyable);
3194 NK_API nk_size nk_prog(struct nk_context*, nk_size cur, nk_size max, int modifyable);
3195 
3196 /* =============================================================================
3197  *
3198  * COLOR PICKER
3199  *
3200  * ============================================================================= */
3203 /* =============================================================================
3204  *
3205  * PROPERTIES
3206  *
3207  * =============================================================================
3278 */
3279 /*/// #### nk_property_int
3298 */
3299 NK_API void nk_property_int(struct nk_context*, const char *name, int min, int *val, int max, int step, float inc_per_pixel);
3300 /*/// #### nk_property_float
3319 */
3320 NK_API void nk_property_float(struct nk_context*, const char *name, float min, float *val, float max, float step, float inc_per_pixel);
3321 /*/// #### nk_property_double
3340 */
3341 NK_API void nk_property_double(struct nk_context*, const char *name, double min, double *val, double max, double step, float inc_per_pixel);
3342 /*/// #### nk_propertyi
3363 */
3364 NK_API int nk_propertyi(struct nk_context*, const char *name, int min, int val, int max, int step, float inc_per_pixel);
3365 /*/// #### nk_propertyf
3386 */
3387 NK_API float nk_propertyf(struct nk_context*, const char *name, float min, float val, float max, float step, float inc_per_pixel);
3388 /*/// #### nk_propertyd
3409 */
3410 NK_API double nk_propertyd(struct nk_context*, const char *name, double min, double val, double max, double step, float inc_per_pixel);
3411 /* =============================================================================
3412  *
3413  * TEXT EDIT
3414  *
3415  * ============================================================================= */
3430 };
3436 };
3438  NK_EDIT_ACTIVE = NK_FLAG(0), /* edit widget is currently being modified */
3439  NK_EDIT_INACTIVE = NK_FLAG(1), /* edit widget is not active and is not being modified */
3440  NK_EDIT_ACTIVATED = NK_FLAG(2), /* edit widget went from state inactive to state active */
3441  NK_EDIT_DEACTIVATED = NK_FLAG(3), /* edit widget went from state active to state inactive */
3442  NK_EDIT_COMMITED = NK_FLAG(4) /* edit widget has received an enter and lost focus */
3443 };
3444 NK_API nk_flags nk_edit_string(struct nk_context*, nk_flags, char *buffer, int *len, int max, nk_plugin_filter);
3449 /* =============================================================================
3450  *
3451  * CHART
3452  *
3453  * ============================================================================= */
3454 NK_API int nk_chart_begin(struct nk_context*, enum nk_chart_type, int num, float min, float max);
3455 NK_API int nk_chart_begin_colored(struct nk_context*, enum nk_chart_type, struct nk_color, struct nk_color active, int num, float min, float max);
3456 NK_API void nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type, int count, float min_value, float max_value);
3457 NK_API void nk_chart_add_slot_colored(struct nk_context *ctx, const enum nk_chart_type, struct nk_color, struct nk_color active, int count, float min_value, float max_value);
3461 NK_API void nk_plot(struct nk_context*, enum nk_chart_type, const float *values, int count, int offset);
3462 NK_API void nk_plot_function(struct nk_context*, enum nk_chart_type, void *userdata, float(*value_getter)(void* user, int index), int count, int offset);
3463 /* =============================================================================
3464  *
3465  * POPUP
3466  *
3467  * ============================================================================= */
3468 NK_API int nk_popup_begin(struct nk_context*, enum nk_popup_type, const char*, nk_flags, struct nk_rect bounds);
3471 NK_API void nk_popup_get_scroll(struct nk_context*, nk_uint *offset_x, nk_uint *offset_y);
3472 NK_API void nk_popup_set_scroll(struct nk_context*, nk_uint offset_x, nk_uint offset_y);
3473 /* =============================================================================
3474  *
3475  * COMBOBOX
3476  *
3477  * ============================================================================= */
3478 NK_API int nk_combo(struct nk_context*, const char **items, int count, int selected, int item_height, struct nk_vec2 size);
3479 NK_API int nk_combo_separator(struct nk_context*, const char *items_separated_by_separator, int separator, int selected, int count, int item_height, struct nk_vec2 size);
3480 NK_API int nk_combo_string(struct nk_context*, const char *items_separated_by_zeros, int selected, int count, int item_height, struct nk_vec2 size);
3481 NK_API int nk_combo_callback(struct nk_context*, void(*item_getter)(void*, int, const char**), void *userdata, int selected, int count, int item_height, struct nk_vec2 size);
3482 NK_API void nk_combobox(struct nk_context*, const char **items, int count, int *selected, int item_height, struct nk_vec2 size);
3483 NK_API void nk_combobox_string(struct nk_context*, const char *items_separated_by_zeros, int *selected, int count, int item_height, struct nk_vec2 size);
3484 NK_API void nk_combobox_separator(struct nk_context*, const char *items_separated_by_separator, int separator,int *selected, int count, int item_height, struct nk_vec2 size);
3485 NK_API void nk_combobox_callback(struct nk_context*, void(*item_getter)(void*, int, const char**), void*, int *selected, int count, int item_height, struct nk_vec2 size);
3486 /* =============================================================================
3487  *
3488  * ABSTRACT COMBOBOX
3489  *
3490  * ============================================================================= */
3491 NK_API int nk_combo_begin_text(struct nk_context*, const char *selected, int, struct nk_vec2 size);
3492 NK_API int nk_combo_begin_label(struct nk_context*, const char *selected, struct nk_vec2 size);
3493 NK_API int nk_combo_begin_color(struct nk_context*, struct nk_color color, struct nk_vec2 size);
3495 NK_API int nk_combo_begin_symbol_label(struct nk_context*, const char *selected, enum nk_symbol_type, struct nk_vec2 size);
3496 NK_API int nk_combo_begin_symbol_text(struct nk_context*, const char *selected, int, enum nk_symbol_type, struct nk_vec2 size);
3497 NK_API int nk_combo_begin_image(struct nk_context*, struct nk_image img, struct nk_vec2 size);
3498 NK_API int nk_combo_begin_image_label(struct nk_context*, const char *selected, struct nk_image, struct nk_vec2 size);
3499 NK_API int nk_combo_begin_image_text(struct nk_context*, const char *selected, int, struct nk_image, struct nk_vec2 size);
3500 NK_API int nk_combo_item_label(struct nk_context*, const char*, nk_flags alignment);
3501 NK_API int nk_combo_item_text(struct nk_context*, const char*,int, nk_flags alignment);
3502 NK_API int nk_combo_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment);
3503 NK_API int nk_combo_item_image_text(struct nk_context*, struct nk_image, const char*, int,nk_flags alignment);
3504 NK_API int nk_combo_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment);
3505 NK_API int nk_combo_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
3508 /* =============================================================================
3509  *
3510  * CONTEXTUAL
3511  *
3512  * ============================================================================= */
3513 NK_API int nk_contextual_begin(struct nk_context*, nk_flags, struct nk_vec2, struct nk_rect trigger_bounds);
3514 NK_API int nk_contextual_item_text(struct nk_context*, const char*, int,nk_flags align);
3515 NK_API int nk_contextual_item_label(struct nk_context*, const char*, nk_flags align);
3516 NK_API int nk_contextual_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment);
3517 NK_API int nk_contextual_item_image_text(struct nk_context*, struct nk_image, const char*, int len, nk_flags alignment);
3518 NK_API int nk_contextual_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment);
3519 NK_API int nk_contextual_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
3522 /* =============================================================================
3523  *
3524  * TOOLTIP
3525  *
3526  * ============================================================================= */
3527 NK_API void nk_tooltip(struct nk_context*, const char*);
3528 #ifdef NK_INCLUDE_STANDARD_VARARGS
3529 NK_API void nk_tooltipf(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, ...) NK_PRINTF_VARARG_FUNC(2);
3530 NK_API void nk_tooltipfv(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(2);
3531 #endif
3532 NK_API int nk_tooltip_begin(struct nk_context*, float width);
3534 /* =============================================================================
3535  *
3536  * MENU
3537  *
3538  * ============================================================================= */
3541 NK_API int nk_menu_begin_text(struct nk_context*, const char* title, int title_len, nk_flags align, struct nk_vec2 size);
3542 NK_API int nk_menu_begin_label(struct nk_context*, const char*, nk_flags align, struct nk_vec2 size);
3543 NK_API int nk_menu_begin_image(struct nk_context*, const char*, struct nk_image, struct nk_vec2 size);
3544 NK_API int nk_menu_begin_image_text(struct nk_context*, const char*, int,nk_flags align,struct nk_image, struct nk_vec2 size);
3545 NK_API int nk_menu_begin_image_label(struct nk_context*, const char*, nk_flags align,struct nk_image, struct nk_vec2 size);
3546 NK_API int nk_menu_begin_symbol(struct nk_context*, const char*, enum nk_symbol_type, struct nk_vec2 size);
3547 NK_API int nk_menu_begin_symbol_text(struct nk_context*, const char*, int,nk_flags align,enum nk_symbol_type, struct nk_vec2 size);
3548 NK_API int nk_menu_begin_symbol_label(struct nk_context*, const char*, nk_flags align,enum nk_symbol_type, struct nk_vec2 size);
3549 NK_API int nk_menu_item_text(struct nk_context*, const char*, int,nk_flags align);
3550 NK_API int nk_menu_item_label(struct nk_context*, const char*, nk_flags alignment);
3551 NK_API int nk_menu_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment);
3552 NK_API int nk_menu_item_image_text(struct nk_context*, struct nk_image, const char*, int len, nk_flags alignment);
3553 NK_API int nk_menu_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
3554 NK_API int nk_menu_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment);
3557 /* =============================================================================
3558  *
3559  * STYLE
3560  *
3561  * ============================================================================= */
3592 };
3602 };
3604 NK_API void nk_style_from_table(struct nk_context*, const struct nk_color*);
3608 NK_API void nk_style_set_font(struct nk_context*, const struct nk_user_font*);
3612 
3613 NK_API int nk_style_push_font(struct nk_context*, const struct nk_user_font*);
3614 NK_API int nk_style_push_float(struct nk_context*, float*, float);
3615 NK_API int nk_style_push_vec2(struct nk_context*, struct nk_vec2*, struct nk_vec2);
3619 
3626 /* =============================================================================
3627  *
3628  * COLOR
3629  *
3630  * ============================================================================= */
3631 NK_API struct nk_color nk_rgb(int r, int g, int b);
3632 NK_API struct nk_color nk_rgb_iv(const int *rgb);
3633 NK_API struct nk_color nk_rgb_bv(const nk_byte* rgb);
3634 NK_API struct nk_color nk_rgb_f(float r, float g, float b);
3635 NK_API struct nk_color nk_rgb_fv(const float *rgb);
3637 NK_API struct nk_color nk_rgb_hex(const char *rgb);
3638 
3639 NK_API struct nk_color nk_rgba(int r, int g, int b, int a);
3641 NK_API struct nk_color nk_rgba_iv(const int *rgba);
3642 NK_API struct nk_color nk_rgba_bv(const nk_byte *rgba);
3643 NK_API struct nk_color nk_rgba_f(float r, float g, float b, float a);
3644 NK_API struct nk_color nk_rgba_fv(const float *rgba);
3646 NK_API struct nk_color nk_rgba_hex(const char *rgb);
3647 
3648 NK_API struct nk_colorf nk_hsva_colorf(float h, float s, float v, float a);
3650 NK_API void nk_colorf_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_colorf in);
3651 NK_API void nk_colorf_hsva_fv(float *hsva, struct nk_colorf in);
3652 
3653 NK_API struct nk_color nk_hsv(int h, int s, int v);
3654 NK_API struct nk_color nk_hsv_iv(const int *hsv);
3655 NK_API struct nk_color nk_hsv_bv(const nk_byte *hsv);
3656 NK_API struct nk_color nk_hsv_f(float h, float s, float v);
3657 NK_API struct nk_color nk_hsv_fv(const float *hsv);
3658 
3659 NK_API struct nk_color nk_hsva(int h, int s, int v, int a);
3660 NK_API struct nk_color nk_hsva_iv(const int *hsva);
3661 NK_API struct nk_color nk_hsva_bv(const nk_byte *hsva);
3662 NK_API struct nk_color nk_hsva_f(float h, float s, float v, float a);
3663 NK_API struct nk_color nk_hsva_fv(const float *hsva);
3664 
3665 /* color (conversion nuklear --> user) */
3666 NK_API void nk_color_f(float *r, float *g, float *b, float *a, struct nk_color);
3667 NK_API void nk_color_fv(float *rgba_out, struct nk_color);
3669 NK_API void nk_color_d(double *r, double *g, double *b, double *a, struct nk_color);
3670 NK_API void nk_color_dv(double *rgba_out, struct nk_color);
3671 
3673 NK_API void nk_color_hex_rgba(char *output, struct nk_color);
3674 NK_API void nk_color_hex_rgb(char *output, struct nk_color);
3675 
3676 NK_API void nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color);
3677 NK_API void nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color);
3678 NK_API void nk_color_hsv_iv(int *hsv_out, struct nk_color);
3679 NK_API void nk_color_hsv_bv(nk_byte *hsv_out, struct nk_color);
3680 NK_API void nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color);
3681 NK_API void nk_color_hsv_fv(float *hsv_out, struct nk_color);
3682 
3683 NK_API void nk_color_hsva_i(int *h, int *s, int *v, int *a, struct nk_color);
3685 NK_API void nk_color_hsva_iv(int *hsva_out, struct nk_color);
3686 NK_API void nk_color_hsva_bv(nk_byte *hsva_out, struct nk_color);
3687 NK_API void nk_color_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_color);
3688 NK_API void nk_color_hsva_fv(float *hsva_out, struct nk_color);
3689 /* =============================================================================
3690  *
3691  * IMAGE
3692  *
3693  * ============================================================================= */
3699 NK_API int nk_image_is_subimage(const struct nk_image* img);
3700 NK_API struct nk_image nk_subimage_ptr(void*, unsigned short w, unsigned short h, struct nk_rect sub_region);
3701 NK_API struct nk_image nk_subimage_id(int, unsigned short w, unsigned short h, struct nk_rect sub_region);
3702 NK_API struct nk_image nk_subimage_handle(nk_handle, unsigned short w, unsigned short h, struct nk_rect sub_region);
3703 /* =============================================================================
3704  *
3705  * MATH
3706  *
3707  * ============================================================================= */
3708 NK_API nk_hash nk_murmur_hash(const void *key, int len, nk_hash seed);
3709 NK_API void nk_triangle_from_direction(struct nk_vec2 *result, struct nk_rect r, float pad_x, float pad_y, enum nk_heading);
3710 
3711 NK_API struct nk_vec2 nk_vec2(float x, float y);
3712 NK_API struct nk_vec2 nk_vec2i(int x, int y);
3713 NK_API struct nk_vec2 nk_vec2v(const float *xy);
3714 NK_API struct nk_vec2 nk_vec2iv(const int *xy);
3715 
3717 NK_API struct nk_rect nk_rect(float x, float y, float w, float h);
3718 NK_API struct nk_rect nk_recti(int x, int y, int w, int h);
3719 NK_API struct nk_rect nk_recta(struct nk_vec2 pos, struct nk_vec2 size);
3720 NK_API struct nk_rect nk_rectv(const float *xywh);
3721 NK_API struct nk_rect nk_rectiv(const int *xywh);
3724 /* =============================================================================
3725  *
3726  * STRING
3727  *
3728  * ============================================================================= */
3729 NK_API int nk_strlen(const char *str);
3730 NK_API int nk_stricmp(const char *s1, const char *s2);
3731 NK_API int nk_stricmpn(const char *s1, const char *s2, int n);
3732 NK_API int nk_strtoi(const char *str, const char **endptr);
3733 NK_API float nk_strtof(const char *str, const char **endptr);
3734 NK_API double nk_strtod(const char *str, const char **endptr);
3735 NK_API int nk_strfilter(const char *text, const char *regexp);
3736 NK_API int nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score);
3737 NK_API int nk_strmatch_fuzzy_text(const char *txt, int txt_len, const char *pattern, int *out_score);
3738 /* =============================================================================
3739  *
3740  * UTF-8
3741  *
3742  * ============================================================================= */
3743 NK_API int nk_utf_decode(const char*, nk_rune*, int);
3744 NK_API int nk_utf_encode(nk_rune, char*, int);
3745 NK_API int nk_utf_len(const char*, int byte_len);
3746 NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune *unicode, int *len);
3747 /* ===============================================================
3748  *
3749  * FONT
3750  *
3751  * ===============================================================*/
3752 /* Font handling in this library was designed to be quite customizable and lets
3753  you decide what you want to use and what you want to provide. There are three
3754  different ways to use the font atlas. The first two will use your font
3755  handling scheme and only requires essential data to run nuklear. The next
3756  slightly more advanced features is font handling with vertex buffer output.
3757  Finally the most complex API wise is using nuklear's font baking API.
3758 
3759  1.) Using your own implementation without vertex buffer output
3760  --------------------------------------------------------------
3761  So first up the easiest way to do font handling is by just providing a
3762  `nk_user_font` struct which only requires the height in pixel of the used
3763  font and a callback to calculate the width of a string. This way of handling
3764  fonts is best fitted for using the normal draw shape command API where you
3765  do all the text drawing yourself and the library does not require any kind
3766  of deeper knowledge about which font handling mechanism you use.
3767  IMPORTANT: the `nk_user_font` pointer provided to nuklear has to persist
3768  over the complete life time! I know this sucks but it is currently the only
3769  way to switch between fonts.
3770 
3771  float your_text_width_calculation(nk_handle handle, float height, const char *text, int len)
3772  {
3773  your_font_type *type = handle.ptr;
3774  float text_width = ...;
3775  return text_width;
3776  }
3777 
3778  struct nk_user_font font;
3779  font.userdata.ptr = &your_font_class_or_struct;
3780  font.height = your_font_height;
3781  font.width = your_text_width_calculation;
3782 
3783  struct nk_context ctx;
3784  nk_init_default(&ctx, &font);
3785 
3786  2.) Using your own implementation with vertex buffer output
3787  --------------------------------------------------------------
3788  While the first approach works fine if you don't want to use the optional
3789  vertex buffer output it is not enough if you do. To get font handling working
3790  for these cases you have to provide two additional parameters inside the
3791  `nk_user_font`. First a texture atlas handle used to draw text as subimages
3792  of a bigger font atlas texture and a callback to query a character's glyph
3793  information (offset, size, ...). So it is still possible to provide your own
3794  font and use the vertex buffer output.
3795 
3796  float your_text_width_calculation(nk_handle handle, float height, const char *text, int len)
3797  {
3798  your_font_type *type = handle.ptr;
3799  float text_width = ...;
3800  return text_width;
3801  }
3802  void query_your_font_glyph(nk_handle handle, float font_height, struct nk_user_font_glyph *glyph, nk_rune codepoint, nk_rune next_codepoint)
3803  {
3804  your_font_type *type = handle.ptr;
3805  glyph.width = ...;
3806  glyph.height = ...;
3807  glyph.xadvance = ...;
3808  glyph.uv[0].x = ...;
3809  glyph.uv[0].y = ...;
3810  glyph.uv[1].x = ...;
3811  glyph.uv[1].y = ...;
3812  glyph.offset.x = ...;
3813  glyph.offset.y = ...;
3814  }
3815 
3816  struct nk_user_font font;
3817  font.userdata.ptr = &your_font_class_or_struct;
3818  font.height = your_font_height;
3819  font.width = your_text_width_calculation;
3820  font.query = query_your_font_glyph;
3821  font.texture.id = your_font_texture;
3822 
3823  struct nk_context ctx;
3824  nk_init_default(&ctx, &font);
3825 
3826  3.) Nuklear font baker
3827  ------------------------------------
3828  The final approach if you do not have a font handling functionality or don't
3829  want to use it in this library is by using the optional font baker.
3830  The font baker APIs can be used to create a font plus font atlas texture
3831  and can be used with or without the vertex buffer output.
3832 
3833  It still uses the `nk_user_font` struct and the two different approaches
3834  previously stated still work. The font baker is not located inside
3835  `nk_context` like all other systems since it can be understood as more of
3836  an extension to nuklear and does not really depend on any `nk_context` state.
3837 
3838  Font baker need to be initialized first by one of the nk_font_atlas_init_xxx
3839  functions. If you don't care about memory just call the default version
3840  `nk_font_atlas_init_default` which will allocate all memory from the standard library.
3841  If you want to control memory allocation but you don't care if the allocated
3842  memory is temporary and therefore can be freed directly after the baking process
3843  is over or permanent you can call `nk_font_atlas_init`.
3844 
3845  After successfully initializing the font baker you can add Truetype(.ttf) fonts from
3846  different sources like memory or from file by calling one of the `nk_font_atlas_add_xxx`.
3847  functions. Adding font will permanently store each font, font config and ttf memory block(!)
3848  inside the font atlas and allows to reuse the font atlas. If you don't want to reuse
3849  the font baker by for example adding additional fonts you can call
3850  `nk_font_atlas_cleanup` after the baking process is over (after calling nk_font_atlas_end).
3851 
3852  As soon as you added all fonts you wanted you can now start the baking process
3853  for every selected glyph to image by calling `nk_font_atlas_bake`.
3854  The baking process returns image memory, width and height which can be used to
3855  either create your own image object or upload it to any graphics library.
3856  No matter which case you finally have to call `nk_font_atlas_end` which
3857  will free all temporary memory including the font atlas image so make sure
3858  you created our texture beforehand. `nk_font_atlas_end` requires a handle
3859  to your font texture or object and optionally fills a `struct nk_draw_null_texture`
3860  which can be used for the optional vertex output. If you don't want it just
3861  set the argument to `NULL`.
3862 
3863  At this point you are done and if you don't want to reuse the font atlas you
3864  can call `nk_font_atlas_cleanup` to free all truetype blobs and configuration
3865  memory. Finally if you don't use the font atlas and any of it's fonts anymore
3866  you need to call `nk_font_atlas_clear` to free all memory still being used.
3867 
3868  struct nk_font_atlas atlas;
3869  nk_font_atlas_init_default(&atlas);
3870  nk_font_atlas_begin(&atlas);
3871  nk_font *font = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font.ttf", 13, 0);
3872  nk_font *font2 = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font2.ttf", 16, 0);
3873  const void* img = nk_font_atlas_bake(&atlas, &img_width, &img_height, NK_FONT_ATLAS_RGBA32);
3874  nk_font_atlas_end(&atlas, nk_handle_id(texture), 0);
3875 
3876  struct nk_context ctx;
3877  nk_init_default(&ctx, &font->handle);
3878  while (1) {
3879 
3880  }
3881  nk_font_atlas_clear(&atlas);
3882 
3883  The font baker API is probably the most complex API inside this library and
3884  I would suggest reading some of my examples `example/` to get a grip on how
3885  to use the font atlas. There are a number of details I left out. For example
3886  how to merge fonts, configure a font with `nk_font_config` to use other languages,
3887  use another texture coordinate format and a lot more:
3888 
3889  struct nk_font_config cfg = nk_font_config(font_pixel_height);
3890  cfg.merge_mode = nk_false or nk_true;
3891  cfg.range = nk_font_korean_glyph_ranges();
3892  cfg.coord_type = NK_COORD_PIXEL;
3893  nk_font *font = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font.ttf", 13, &cfg);
3894 
3895 */
3896 struct nk_user_font_glyph;
3897 typedef float(*nk_text_width_f)(nk_handle, float h, const char*, int len);
3898 typedef void(*nk_query_font_glyph_f)(nk_handle handle, float font_height,
3899  struct nk_user_font_glyph *glyph,
3900  nk_rune codepoint, nk_rune next_codepoint);
3901 
3902 #if defined(NK_INCLUDE_VERTEX_BUFFER_OUTPUT) || defined(NK_INCLUDE_SOFTWARE_FONT)
3903 struct nk_user_font_glyph {
3904  struct nk_vec2 uv[2];
3905  /* texture coordinates */
3906  struct nk_vec2 offset;
3907  /* offset between top left and glyph */
3908  float width, height;
3909  /* size of the glyph */
3910  float xadvance;
3911  /* offset to the next glyph */
3912 };
3913 #endif
3914 
3917  /* user provided font handle */
3918  float height;
3919  /* max height of the font */
3921  /* font string width in pixel callback */
3922 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
3923  nk_query_font_glyph_f query;
3924  /* font glyph callback to query drawing info */
3925  nk_handle texture;
3926  /* texture handle to the used font atlas or texture */
3927 #endif
3928 };
3929 
3930 #ifdef NK_INCLUDE_FONT_BAKING
3931 enum nk_font_coord_type {
3932  NK_COORD_UV, /* texture coordinates inside font glyphs are clamped between 0-1 */
3933  NK_COORD_PIXEL /* texture coordinates inside font glyphs are in absolute pixel */
3934 };
3935 
3936 struct nk_font;
3937 struct nk_baked_font {
3938  float height;
3939  /* height of the font */
3940  float ascent, descent;
3941  /* font glyphs ascent and descent */
3942  nk_rune glyph_offset;
3943  /* glyph array offset inside the font glyph baking output array */
3944  nk_rune glyph_count;
3945  /* number of glyphs of this font inside the glyph baking array output */
3946  const nk_rune *ranges;
3947  /* font codepoint ranges as pairs of (from/to) and 0 as last element */
3948 };
3949 
3950 struct nk_font_config {
3951  struct nk_font_config *next;
3952  /* NOTE: only used internally */
3953  void *ttf_blob;
3954  /* pointer to loaded TTF file memory block.
3955  * NOTE: not needed for nk_font_atlas_add_from_memory and nk_font_atlas_add_from_file. */
3956  nk_size ttf_size;
3957  /* size of the loaded TTF file memory block
3958  * NOTE: not needed for nk_font_atlas_add_from_memory and nk_font_atlas_add_from_file. */
3959 
3960  unsigned char ttf_data_owned_by_atlas;
3961  /* used inside font atlas: default to: 0*/
3962  unsigned char merge_mode;
3963  /* merges this font into the last font */
3964  unsigned char pixel_snap;
3965  /* align every character to pixel boundary (if true set oversample (1,1)) */
3966  unsigned char oversample_v, oversample_h;
3967  /* rasterize at hight quality for sub-pixel position */
3968  unsigned char padding[3];
3969 
3970  float size;
3971  /* baked pixel height of the font */
3972  enum nk_font_coord_type coord_type;
3973  /* texture coordinate format with either pixel or UV coordinates */
3974  struct nk_vec2 spacing;
3975  /* extra pixel spacing between glyphs */
3976  const nk_rune *range;
3977  /* list of unicode ranges (2 values per range, zero terminated) */
3978  struct nk_baked_font *font;
3979  /* font to setup in the baking process: NOTE: not needed for font atlas */
3980  nk_rune fallback_glyph;
3981  /* fallback glyph to use if a given rune is not found */
3982  struct nk_font_config *n;
3983  struct nk_font_config *p;
3984 };
3985 
3986 struct nk_font_glyph {
3987  nk_rune codepoint;
3988  float xadvance;
3989  float x0, y0, x1, y1, w, h;
3990  float u0, v0, u1, v1;
3991 };
3992 
3993 struct nk_font {
3994  struct nk_font *next;
3995  struct nk_user_font handle;
3996  struct nk_baked_font info;
3997  float scale;
3998  struct nk_font_glyph *glyphs;
3999  const struct nk_font_glyph *fallback;
4000  nk_rune fallback_codepoint;
4001  nk_handle texture;
4002  struct nk_font_config *config;
4003 };
4004 
4005 enum nk_font_atlas_format {
4006  NK_FONT_ATLAS_ALPHA8,
4007  NK_FONT_ATLAS_RGBA32
4008 };
4009 
4010 struct nk_font_atlas {
4011  void *pixel;
4012  int tex_width;
4013  int tex_height;
4014 
4015  struct nk_allocator permanent;
4016  struct nk_allocator temporary;
4017 
4018  struct nk_recti custom;
4019  struct nk_cursor cursors[NK_CURSOR_COUNT];
4020 
4021  int glyph_count;
4022  struct nk_font_glyph *glyphs;
4023  struct nk_font *default_font;
4024  struct nk_font *fonts;
4025  struct nk_font_config *config;
4026  int font_num;
4027 };
4028 
4029 /* some language glyph codepoint ranges */
4030 NK_API const nk_rune *nk_font_default_glyph_ranges(void);
4031 NK_API const nk_rune *nk_font_chinese_glyph_ranges(void);
4032 NK_API const nk_rune *nk_font_cyrillic_glyph_ranges(void);
4033 NK_API const nk_rune *nk_font_korean_glyph_ranges(void);
4034 
4035 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4036 NK_API void nk_font_atlas_init_default(struct nk_font_atlas*);
4037 #endif
4038 NK_API void nk_font_atlas_init(struct nk_font_atlas*, struct nk_allocator*);
4039 NK_API void nk_font_atlas_init_custom(struct nk_font_atlas*, struct nk_allocator *persistent, struct nk_allocator *transient);
4040 NK_API void nk_font_atlas_begin(struct nk_font_atlas*);
4041 NK_API struct nk_font_config nk_font_config(float pixel_height);
4042 NK_API struct nk_font *nk_font_atlas_add(struct nk_font_atlas*, const struct nk_font_config*);
4043 #ifdef NK_INCLUDE_DEFAULT_FONT
4044 NK_API struct nk_font* nk_font_atlas_add_default(struct nk_font_atlas*, float height, const struct nk_font_config*);
4045 #endif
4046 NK_API struct nk_font* nk_font_atlas_add_from_memory(struct nk_font_atlas *atlas, void *memory, nk_size size, float height, const struct nk_font_config *config);
4047 #ifdef NK_INCLUDE_STANDARD_IO
4048 NK_API struct nk_font* nk_font_atlas_add_from_file(struct nk_font_atlas *atlas, const char *file_path, float height, const struct nk_font_config*);
4049 #endif
4050 NK_API struct nk_font *nk_font_atlas_add_compressed(struct nk_font_atlas*, void *memory, nk_size size, float height, const struct nk_font_config*);
4051 NK_API struct nk_font* nk_font_atlas_add_compressed_base85(struct nk_font_atlas*, const char *data, float height, const struct nk_font_config *config);
4052 NK_API const void* nk_font_atlas_bake(struct nk_font_atlas*, int *width, int *height, enum nk_font_atlas_format);
4053 NK_API void nk_font_atlas_end(struct nk_font_atlas*, nk_handle tex, struct nk_draw_null_texture*);
4054 NK_API const struct nk_font_glyph* nk_font_find_glyph(struct nk_font*, nk_rune unicode);
4055 NK_API void nk_font_atlas_cleanup(struct nk_font_atlas *atlas);
4056 NK_API void nk_font_atlas_clear(struct nk_font_atlas*);
4057 
4058 #endif
4059 
4060 /* ==============================================================
4061  *
4062  * MEMORY BUFFER
4063  *
4064  * ===============================================================*/
4065 /* A basic (double)-buffer with linear allocation and resetting as only
4066  freeing policy. The buffer's main purpose is to control all memory management
4067  inside the GUI toolkit and still leave memory control as much as possible in
4068  the hand of the user while also making sure the library is easy to use if
4069  not as much control is needed.
4070  In general all memory inside this library can be provided from the user in
4071  three different ways.
4072 
4073  The first way and the one providing most control is by just passing a fixed
4074  size memory block. In this case all control lies in the hand of the user
4075  since he can exactly control where the memory comes from and how much memory
4076  the library should consume. Of course using the fixed size API removes the
4077  ability to automatically resize a buffer if not enough memory is provided so
4078  you have to take over the resizing. While being a fixed sized buffer sounds
4079  quite limiting, it is very effective in this library since the actual memory
4080  consumption is quite stable and has a fixed upper bound for a lot of cases.
4081 
4082  If you don't want to think about how much memory the library should allocate
4083  at all time or have a very dynamic UI with unpredictable memory consumption
4084  habits but still want control over memory allocation you can use the dynamic
4085  allocator based API. The allocator consists of two callbacks for allocating
4086  and freeing memory and optional userdata so you can plugin your own allocator.
4087 
4088  The final and easiest way can be used by defining
4089  NK_INCLUDE_DEFAULT_ALLOCATOR which uses the standard library memory
4090  allocation functions malloc and free and takes over complete control over
4091  memory in this library.
4092 */
4094  void *memory;
4095  unsigned int type;
4100 };
4101 
4105 };
4106 
4111 };
4112 
4114  int active;
4116 };
4117 
4118 struct nk_memory {void *ptr;nk_size size;};
4119 struct nk_buffer {
4121  /* buffer marker to free a buffer to a certain offset */
4122  struct nk_allocator pool;
4123  /* allocator callback for dynamic buffers */
4124  enum nk_allocation_type type;
4125  /* memory management type */
4126  struct nk_memory memory;
4127  /* memory and size of the current memory block */
4129  /* growing factor for dynamic memory management */
4131  /* total amount of memory allocated */
4133  /* totally consumed memory given that enough memory is present */
4135  /* number of allocation calls */
4137  /* current size of the buffer */
4138 };
4139 
4140 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4141 NK_API void nk_buffer_init_default(struct nk_buffer*);
4142 #endif
4143 NK_API void nk_buffer_init(struct nk_buffer*, const struct nk_allocator*, nk_size size);
4144 NK_API void nk_buffer_init_fixed(struct nk_buffer*, void *memory, nk_size size);
4146 NK_API void nk_buffer_push(struct nk_buffer*, enum nk_buffer_allocation_type type, const void *memory, nk_size size, nk_size align);
4152 NK_API const void *nk_buffer_memory_const(const struct nk_buffer*);
4154 
4155 /* ==============================================================
4156  *
4157  * STRING
4158  *
4159  * ===============================================================*/
4160 /* Basic string buffer which is only used in context with the text editor
4161  * to manage and manipulate dynamic or fixed size string content. This is _NOT_
4162  * the default string handling method. The only instance you should have any contact
4163  * with this API is if you interact with an `nk_text_edit` object inside one of the
4164  * copy and paste functions and even there only for more advanced cases. */
4165 struct nk_str {
4166  struct nk_buffer buffer;
4167  int len; /* in codepoints/runes/glyphs */
4168 };
4169 
4170 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4171 NK_API void nk_str_init_default(struct nk_str*);
4172 #endif
4173 NK_API void nk_str_init(struct nk_str*, const struct nk_allocator*, nk_size size);
4176 NK_API void nk_str_free(struct nk_str*);
4177 
4178 NK_API int nk_str_append_text_char(struct nk_str*, const char*, int);
4179 NK_API int nk_str_append_str_char(struct nk_str*, const char*);
4180 NK_API int nk_str_append_text_utf8(struct nk_str*, const char*, int);
4181 NK_API int nk_str_append_str_utf8(struct nk_str*, const char*);
4182 NK_API int nk_str_append_text_runes(struct nk_str*, const nk_rune*, int);
4184 
4185 NK_API int nk_str_insert_at_char(struct nk_str*, int pos, const char*, int);
4186 NK_API int nk_str_insert_at_rune(struct nk_str*, int pos, const char*, int);
4187 
4188 NK_API int nk_str_insert_text_char(struct nk_str*, int pos, const char*, int);
4189 NK_API int nk_str_insert_str_char(struct nk_str*, int pos, const char*);
4190 NK_API int nk_str_insert_text_utf8(struct nk_str*, int pos, const char*, int);
4191 NK_API int nk_str_insert_str_utf8(struct nk_str*, int pos, const char*);
4192 NK_API int nk_str_insert_text_runes(struct nk_str*, int pos, const nk_rune*, int);
4193 NK_API int nk_str_insert_str_runes(struct nk_str*, int pos, const nk_rune*);
4194 
4195 NK_API void nk_str_remove_chars(struct nk_str*, int len);
4196 NK_API void nk_str_remove_runes(struct nk_str *str, int len);
4197 NK_API void nk_str_delete_chars(struct nk_str*, int pos, int len);
4198 NK_API void nk_str_delete_runes(struct nk_str*, int pos, int len);
4199 
4200 NK_API char *nk_str_at_char(struct nk_str*, int pos);
4201 NK_API char *nk_str_at_rune(struct nk_str*, int pos, nk_rune *unicode, int *len);
4202 NK_API nk_rune nk_str_rune_at(const struct nk_str*, int pos);
4203 NK_API const char *nk_str_at_char_const(const struct nk_str*, int pos);
4204 NK_API const char *nk_str_at_const(const struct nk_str*, int pos, nk_rune *unicode, int *len);
4205 
4206 NK_API char *nk_str_get(struct nk_str*);
4207 NK_API const char *nk_str_get_const(const struct nk_str*);
4208 NK_API int nk_str_len(struct nk_str*);
4210 
4211 /*===============================================================
4212  *
4213  * TEXT EDITOR
4214  *
4215  * ===============================================================*/
4216 /* Editing text in this library is handled by either `nk_edit_string` or
4217  * `nk_edit_buffer`. But like almost everything in this library there are multiple
4218  * ways of doing it and a balance between control and ease of use with memory
4219  * as well as functionality controlled by flags.
4220  *
4221  * This library generally allows three different levels of memory control:
4222  * First of is the most basic way of just providing a simple char array with
4223  * string length. This method is probably the easiest way of handling simple
4224  * user text input. Main upside is complete control over memory while the biggest
4225  * downside in comparison with the other two approaches is missing undo/redo.
4226  *
4227  * For UIs that require undo/redo the second way was created. It is based on
4228  * a fixed size nk_text_edit struct, which has an internal undo/redo stack.
4229  * This is mainly useful if you want something more like a text editor but don't want
4230  * to have a dynamically growing buffer.
4231  *
4232  * The final way is using a dynamically growing nk_text_edit struct, which
4233  * has both a default version if you don't care where memory comes from and an
4234  * allocator version if you do. While the text editor is quite powerful for its
4235  * complexity I would not recommend editing gigabytes of data with it.
4236  * It is rather designed for uses cases which make sense for a GUI library not for
4237  * an full blown text editor.
4238  */
4239 #ifndef NK_TEXTEDIT_UNDOSTATECOUNT
4240 #define NK_TEXTEDIT_UNDOSTATECOUNT 99
4241 #endif
4242 
4243 #ifndef NK_TEXTEDIT_UNDOCHARCOUNT
4244 #define NK_TEXTEDIT_UNDOCHARCOUNT 999
4245 #endif
4246 
4247 struct nk_text_edit;
4252 };
4253 
4255  int where;
4259 };
4260 
4264  short undo_point;
4265  short redo_point;
4268 };
4269 
4273 };
4274 
4279 };
4280 
4282  struct nk_clipboard clip;
4283  struct nk_str string;
4285  struct nk_vec2 scrollbar;
4286 
4287  int cursor;
4290  unsigned char mode;
4291  unsigned char cursor_at_end_of_line;
4292  unsigned char initialized;
4293  unsigned char has_preferred_x;
4294  unsigned char single_line;
4295  unsigned char active;
4296  unsigned char padding1;
4298  struct nk_text_undo_state undo;
4299 };
4300 
4301 /* filter function */
4302 NK_API int nk_filter_default(const struct nk_text_edit*, nk_rune unicode);
4303 NK_API int nk_filter_ascii(const struct nk_text_edit*, nk_rune unicode);
4304 NK_API int nk_filter_float(const struct nk_text_edit*, nk_rune unicode);
4305 NK_API int nk_filter_decimal(const struct nk_text_edit*, nk_rune unicode);
4306 NK_API int nk_filter_hex(const struct nk_text_edit*, nk_rune unicode);
4307 NK_API int nk_filter_oct(const struct nk_text_edit*, nk_rune unicode);
4308 NK_API int nk_filter_binary(const struct nk_text_edit*, nk_rune unicode);
4309 
4310 /* text editor */
4311 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4312 NK_API void nk_textedit_init_default(struct nk_text_edit*);
4313 #endif
4315 NK_API void nk_textedit_init_fixed(struct nk_text_edit*, void *memory, nk_size size);
4317 NK_API void nk_textedit_text(struct nk_text_edit*, const char*, int total_len);
4318 NK_API void nk_textedit_delete(struct nk_text_edit*, int where, int len);
4322 NK_API int nk_textedit_paste(struct nk_text_edit*, char const*, int len);
4325 
4326 /* ===============================================================
4327  *
4328  * DRAWING
4329  *
4330  * ===============================================================*/
4331 /* This library was designed to be render backend agnostic so it does
4332  not draw anything to screen. Instead all drawn shapes, widgets
4333  are made of, are buffered into memory and make up a command queue.
4334  Each frame therefore fills the command buffer with draw commands
4335  that then need to be executed by the user and his own render backend.
4336  After that the command buffer needs to be cleared and a new frame can be
4337  started. It is probably important to note that the command buffer is the main
4338  drawing API and the optional vertex buffer API only takes this format and
4339  converts it into a hardware accessible format.
4340 
4341  To use the command queue to draw your own widgets you can access the
4342  command buffer of each window by calling `nk_window_get_canvas` after
4343  previously having called `nk_begin`:
4344 
4345  void draw_red_rectangle_widget(struct nk_context *ctx)
4346  {
4347  struct nk_command_buffer *canvas;
4348  struct nk_input *input = &ctx->input;
4349  canvas = nk_window_get_canvas(ctx);
4350 
4351  struct nk_rect space;
4352  enum nk_widget_layout_states state;
4353  state = nk_widget(&space, ctx);
4354  if (!state) return;
4355 
4356  if (state != NK_WIDGET_ROM)
4357  update_your_widget_by_user_input(...);
4358  nk_fill_rect(canvas, space, 0, nk_rgb(255,0,0));
4359  }
4360 
4361  if (nk_begin(...)) {
4362  nk_layout_row_dynamic(ctx, 25, 1);
4363  draw_red_rectangle_widget(ctx);
4364  }
4365  nk_end(..)
4366 
4367  Important to know if you want to create your own widgets is the `nk_widget`
4368  call. It allocates space on the panel reserved for this widget to be used,
4369  but also returns the state of the widget space. If your widget is not seen and does
4370  not have to be updated it is '0' and you can just return. If it only has
4371  to be drawn the state will be `NK_WIDGET_ROM` otherwise you can do both
4372  update and draw your widget. The reason for separating is to only draw and
4373  update what is actually necessary which is crucial for performance.
4374 */
4395 };
4396 
4397 /* command base and header of every command inside the buffer */
4398 struct nk_command {
4399  enum nk_command_type type;
4401 #ifdef NK_INCLUDE_COMMAND_USERDATA
4402  nk_handle userdata;
4403 #endif
4404 };
4405 
4407  struct nk_command header;
4408  short x, y;
4409  unsigned short w, h;
4410 };
4411 
4413  struct nk_command header;
4414  unsigned short line_thickness;
4415  struct nk_vec2i begin;
4416  struct nk_vec2i end;
4417  struct nk_color color;
4418 };
4419 
4421  struct nk_command header;
4422  unsigned short line_thickness;
4423  struct nk_vec2i begin;
4424  struct nk_vec2i end;
4425  struct nk_vec2i ctrl[2];
4426  struct nk_color color;
4427 };
4428 
4430  struct nk_command header;
4431  unsigned short rounding;
4432  unsigned short line_thickness;
4433  short x, y;
4434  unsigned short w, h;
4435  struct nk_color color;
4436 };
4437 
4439  struct nk_command header;
4440  unsigned short rounding;
4441  short x, y;
4442  unsigned short w, h;
4443  struct nk_color color;
4444 };
4445 
4447  struct nk_command header;
4448  short x, y;
4449  unsigned short w, h;
4450  struct nk_color left;
4451  struct nk_color top;
4452  struct nk_color bottom;
4453  struct nk_color right;
4454 };
4455 
4457  struct nk_command header;
4458  unsigned short line_thickness;
4459  struct nk_vec2i a;
4460  struct nk_vec2i b;
4461  struct nk_vec2i c;
4462  struct nk_color color;
4463 };
4464 
4466  struct nk_command header;
4467  struct nk_vec2i a;
4468  struct nk_vec2i b;
4469  struct nk_vec2i c;
4470  struct nk_color color;
4471 };
4472 
4474  struct nk_command header;
4475  short x, y;
4476  unsigned short line_thickness;
4477  unsigned short w, h;
4478  struct nk_color color;
4479 };
4480 
4482  struct nk_command header;
4483  short x, y;
4484  unsigned short w, h;
4485  struct nk_color color;
4486 };
4487 
4489  struct nk_command header;
4490  short cx, cy;
4491  unsigned short r;
4492  unsigned short line_thickness;
4493  float a[2];
4494  struct nk_color color;
4495 };
4496 
4498  struct nk_command header;
4499  short cx, cy;
4500  unsigned short r;
4501  float a[2];
4502  struct nk_color color;
4503 };
4504 
4506  struct nk_command header;
4507  struct nk_color color;
4508  unsigned short line_thickness;
4509  unsigned short point_count;
4510  struct nk_vec2i points[1];
4511 };
4512 
4514  struct nk_command header;
4515  struct nk_color color;
4516  unsigned short point_count;
4517  struct nk_vec2i points[1];
4518 };
4519 
4521  struct nk_command header;
4522  struct nk_color color;
4523  unsigned short line_thickness;
4524  unsigned short point_count;
4525  struct nk_vec2i points[1];
4526 };
4527 
4529  struct nk_command header;
4530  short x, y;
4531  unsigned short w, h;
4532  struct nk_image img;
4533  struct nk_color col;
4534 };
4535 
4536 typedef void (*nk_command_custom_callback)(void *canvas, short x,short y,
4537  unsigned short w, unsigned short h, nk_handle callback_data);
4539  struct nk_command header;
4540  short x, y;
4541  unsigned short w, h;
4544 };
4545 
4547  struct nk_command header;
4548  const struct nk_user_font *font;
4549  struct nk_color background;
4550  struct nk_color foreground;
4551  short x, y;
4552  unsigned short w, h;
4553  float height;
4554  int length;
4555  char string[1];
4556 };
4557 
4561 };
4562 
4564  struct nk_buffer *base;
4565  struct nk_rect clip;
4569 };
4570 
4571 /* shape outlines */
4572 NK_API void nk_stroke_line(struct nk_command_buffer *b, float x0, float y0, float x1, float y1, float line_thickness, struct nk_color);
4573 NK_API void nk_stroke_curve(struct nk_command_buffer*, float, float, float, float, float, float, float, float, float line_thickness, struct nk_color);
4574 NK_API void nk_stroke_rect(struct nk_command_buffer*, struct nk_rect, float rounding, float line_thickness, struct nk_color);
4575 NK_API void nk_stroke_circle(struct nk_command_buffer*, struct nk_rect, float line_thickness, struct nk_color);
4576 NK_API void nk_stroke_arc(struct nk_command_buffer*, float cx, float cy, float radius, float a_min, float a_max, float line_thickness, struct nk_color);
4577 NK_API void nk_stroke_triangle(struct nk_command_buffer*, float, float, float, float, float, float, float line_thichness, struct nk_color);
4578 NK_API void nk_stroke_polyline(struct nk_command_buffer*, float *points, int point_count, float line_thickness, struct nk_color col);
4579 NK_API void nk_stroke_polygon(struct nk_command_buffer*, float*, int point_count, float line_thickness, struct nk_color);
4580 
4581 /* filled shades */
4582 NK_API void nk_fill_rect(struct nk_command_buffer*, struct nk_rect, float rounding, struct nk_color);
4583 NK_API void nk_fill_rect_multi_color(struct nk_command_buffer*, struct nk_rect, struct nk_color left, struct nk_color top, struct nk_color right, struct nk_color bottom);
4585 NK_API void nk_fill_arc(struct nk_command_buffer*, float cx, float cy, float radius, float a_min, float a_max, struct nk_color);
4586 NK_API void nk_fill_triangle(struct nk_command_buffer*, float x0, float y0, float x1, float y1, float x2, float y2, struct nk_color);
4587 NK_API void nk_fill_polygon(struct nk_command_buffer*, float*, int point_count, struct nk_color);
4588 
4589 /* misc */
4590 NK_API void nk_draw_image(struct nk_command_buffer*, struct nk_rect, const struct nk_image*, struct nk_color);
4591 NK_API void nk_draw_text(struct nk_command_buffer*, struct nk_rect, const char *text, int len, const struct nk_user_font*, struct nk_color, struct nk_color);
4594 
4595 /* ===============================================================
4596  *
4597  * INPUT
4598  *
4599  * ===============================================================*/
4601  int down;
4602  unsigned int clicked;
4603  struct nk_vec2 clicked_pos;
4604 };
4605 struct nk_mouse {
4607  struct nk_vec2 pos;
4608  struct nk_vec2 prev;
4609  struct nk_vec2 delta;
4610  struct nk_vec2 scroll_delta;
4611  unsigned char grab;
4612  unsigned char grabbed;
4613  unsigned char ungrab;
4614 };
4615 
4616 struct nk_key {
4617  int down;
4618  unsigned int clicked;
4619 };
4620 struct nk_keyboard {
4621  struct nk_key keys[NK_KEY_MAX];
4624 };
4625 
4626 struct nk_input {
4627  struct nk_keyboard keyboard;
4628  struct nk_mouse mouse;
4629 };
4630 
4633 NK_API int nk_input_has_mouse_click_down_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect, int down);
4635 NK_API int nk_input_is_mouse_click_down_in_rect(const struct nk_input *i, enum nk_buttons id, struct nk_rect b, int down);
4639 NK_API int nk_input_mouse_clicked(const struct nk_input*, enum nk_buttons, struct nk_rect);
4645 NK_API int nk_input_is_key_down(const struct nk_input*, enum nk_keys);
4646 
4647 /* ===============================================================
4648  *
4649  * DRAW LIST
4650  *
4651  * ===============================================================*/
4652 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
4653 /* The optional vertex buffer draw list provides a 2D drawing context
4654  with antialiasing functionality which takes basic filled or outlined shapes
4655  or a path and outputs vertexes, elements and draw commands.
4656  The actual draw list API is not required to be used directly while using this
4657  library since converting the default library draw command output is done by
4658  just calling `nk_convert` but I decided to still make this library accessible
4659  since it can be useful.
4660 
4661  The draw list is based on a path buffering and polygon and polyline
4662  rendering API which allows a lot of ways to draw 2D content to screen.
4663  In fact it is probably more powerful than needed but allows even more crazy
4664  things than this library provides by default.
4665 */
4666 #ifdef NK_UINT_DRAW_INDEX
4667 typedef nk_uint nk_draw_index;
4668 #else
4669 typedef nk_ushort nk_draw_index;
4670 #endif
4671 enum nk_draw_list_stroke {
4672  NK_STROKE_OPEN = nk_false,
4673  /* build up path has no connection back to the beginning */
4674  NK_STROKE_CLOSED = nk_true
4675  /* build up path has a connection back to the beginning */
4676 };
4677 
4678 enum nk_draw_vertex_layout_attribute {
4679  NK_VERTEX_POSITION,
4680  NK_VERTEX_COLOR,
4681  NK_VERTEX_TEXCOORD,
4682  NK_VERTEX_ATTRIBUTE_COUNT
4683 };
4684 
4685 enum nk_draw_vertex_layout_format {
4686  NK_FORMAT_SCHAR,
4687  NK_FORMAT_SSHORT,
4688  NK_FORMAT_SINT,
4689  NK_FORMAT_UCHAR,
4690  NK_FORMAT_USHORT,
4691  NK_FORMAT_UINT,
4692  NK_FORMAT_FLOAT,
4693  NK_FORMAT_DOUBLE,
4694 
4695 NK_FORMAT_COLOR_BEGIN,
4696  NK_FORMAT_R8G8B8 = NK_FORMAT_COLOR_BEGIN,
4697  NK_FORMAT_R16G15B16,
4698  NK_FORMAT_R32G32B32,
4699 
4700  NK_FORMAT_R8G8B8A8,
4701  NK_FORMAT_B8G8R8A8,
4702  NK_FORMAT_R16G15B16A16,
4703  NK_FORMAT_R32G32B32A32,
4704  NK_FORMAT_R32G32B32A32_FLOAT,
4705  NK_FORMAT_R32G32B32A32_DOUBLE,
4706 
4707  NK_FORMAT_RGB32,
4708  NK_FORMAT_RGBA32,
4709 NK_FORMAT_COLOR_END = NK_FORMAT_RGBA32,
4710  NK_FORMAT_COUNT
4711 };
4712 
4713 #define NK_VERTEX_LAYOUT_END NK_VERTEX_ATTRIBUTE_COUNT,NK_FORMAT_COUNT,0
4714 struct nk_draw_vertex_layout_element {
4715  enum nk_draw_vertex_layout_attribute attribute;
4716  enum nk_draw_vertex_layout_format format;
4717  nk_size offset;
4718 };
4719 
4720 struct nk_draw_command {
4721  unsigned int elem_count;
4722  /* number of elements in the current draw batch */
4723  struct nk_rect clip_rect;
4724  /* current screen clipping rectangle */
4725  nk_handle texture;
4726  /* current texture to set */
4727 #ifdef NK_INCLUDE_COMMAND_USERDATA
4728  nk_handle userdata;
4729 #endif
4730 };
4731 
4732 struct nk_draw_list {
4733  struct nk_rect clip_rect;
4734  struct nk_vec2 circle_vtx[12];
4735  struct nk_convert_config config;
4736 
4737  struct nk_buffer *buffer;
4738  struct nk_buffer *vertices;
4739  struct nk_buffer *elements;
4740 
4741  unsigned int element_count;
4742  unsigned int vertex_count;
4743  unsigned int cmd_count;
4744  nk_size cmd_offset;
4745 
4746  unsigned int path_count;
4747  unsigned int path_offset;
4748 
4749  enum nk_anti_aliasing line_AA;
4750  enum nk_anti_aliasing shape_AA;
4751 
4752 #ifdef NK_INCLUDE_COMMAND_USERDATA
4753  nk_handle userdata;
4754 #endif
4755 };
4756 
4757 /* draw list */
4758 NK_API void nk_draw_list_init(struct nk_draw_list*);
4759 NK_API void nk_draw_list_setup(struct nk_draw_list*, const struct nk_convert_config*, struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements, enum nk_anti_aliasing line_aa,enum nk_anti_aliasing shape_aa);
4760 
4761 /* drawing */
4762 #define nk_draw_list_foreach(cmd, can, b) for((cmd)=nk__draw_list_begin(can, b); (cmd)!=0; (cmd)=nk__draw_list_next(cmd, b, can))
4763 NK_API const struct nk_draw_command* nk__draw_list_begin(const struct nk_draw_list*, const struct nk_buffer*);
4764 NK_API const struct nk_draw_command* nk__draw_list_next(const struct nk_draw_command*, const struct nk_buffer*, const struct nk_draw_list*);
4765 NK_API const struct nk_draw_command* nk__draw_list_end(const struct nk_draw_list*, const struct nk_buffer*);
4766 
4767 /* path */
4768 NK_API void nk_draw_list_path_clear(struct nk_draw_list*);
4769 NK_API void nk_draw_list_path_line_to(struct nk_draw_list*, struct nk_vec2 pos);
4770 NK_API void nk_draw_list_path_arc_to_fast(struct nk_draw_list*, struct nk_vec2 center, float radius, int a_min, int a_max);
4771 NK_API void nk_draw_list_path_arc_to(struct nk_draw_list*, struct nk_vec2 center, float radius, float a_min, float a_max, unsigned int segments);
4772 NK_API void nk_draw_list_path_rect_to(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, float rounding);
4773 NK_API void nk_draw_list_path_curve_to(struct nk_draw_list*, struct nk_vec2 p2, struct nk_vec2 p3, struct nk_vec2 p4, unsigned int num_segments);
4774 NK_API void nk_draw_list_path_fill(struct nk_draw_list*, struct nk_color);
4775 NK_API void nk_draw_list_path_stroke(struct nk_draw_list*, struct nk_color, enum nk_draw_list_stroke closed, float thickness);
4776 
4777 /* stroke */
4778 NK_API void nk_draw_list_stroke_line(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, struct nk_color, float thickness);
4779 NK_API void nk_draw_list_stroke_rect(struct nk_draw_list*, struct nk_rect rect, struct nk_color, float rounding, float thickness);
4780 NK_API void nk_draw_list_stroke_triangle(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, struct nk_vec2 c, struct nk_color, float thickness);
4781 NK_API void nk_draw_list_stroke_circle(struct nk_draw_list*, struct nk_vec2 center, float radius, struct nk_color, unsigned int segs, float thickness);
4782 NK_API void nk_draw_list_stroke_curve(struct nk_draw_list*, struct nk_vec2 p0, struct nk_vec2 cp0, struct nk_vec2 cp1, struct nk_vec2 p1, struct nk_color, unsigned int segments, float thickness);
4783 NK_API void nk_draw_list_stroke_poly_line(struct nk_draw_list*, const struct nk_vec2 *pnts, const unsigned int cnt, struct nk_color, enum nk_draw_list_stroke, float thickness, enum nk_anti_aliasing);
4784 
4785 /* fill */
4786 NK_API void nk_draw_list_fill_rect(struct nk_draw_list*, struct nk_rect rect, struct nk_color, float rounding);
4787 NK_API void nk_draw_list_fill_rect_multi_color(struct nk_draw_list*, struct nk_rect rect, struct nk_color left, struct nk_color top, struct nk_color right, struct nk_color bottom);
4788 NK_API void nk_draw_list_fill_triangle(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, struct nk_vec2 c, struct nk_color);
4789 NK_API void nk_draw_list_fill_circle(struct nk_draw_list*, struct nk_vec2 center, float radius, struct nk_color col, unsigned int segs);
4790 NK_API void nk_draw_list_fill_poly_convex(struct nk_draw_list*, const struct nk_vec2 *points, const unsigned int count, struct nk_color, enum nk_anti_aliasing);
4791 
4792 /* misc */
4793 NK_API void nk_draw_list_add_image(struct nk_draw_list*, struct nk_image texture, struct nk_rect rect, struct nk_color);
4794 NK_API void nk_draw_list_add_text(struct nk_draw_list*, const struct nk_user_font*, struct nk_rect, const char *text, int len, float font_height, struct nk_color);
4795 #ifdef NK_INCLUDE_COMMAND_USERDATA
4796 NK_API void nk_draw_list_push_userdata(struct nk_draw_list*, nk_handle userdata);
4797 #endif
4798 
4799 #endif
4800 
4801 /* ===============================================================
4802  *
4803  * GUI
4804  *
4805  * ===============================================================*/
4809 };
4810 
4812  struct nk_image image;
4813  struct nk_color color;
4814 };
4815 
4817  enum nk_style_item_type type;
4818  union nk_style_item_data data;
4819 };
4820 
4822  struct nk_color color;
4823  struct nk_vec2 padding;
4824 };
4825 
4827  /* background */
4828  struct nk_style_item normal;
4829  struct nk_style_item hover;
4830  struct nk_style_item active;
4831  struct nk_color border_color;
4832 
4833  /* text */
4834  struct nk_color text_background;
4835  struct nk_color text_normal;
4836  struct nk_color text_hover;
4837  struct nk_color text_active;
4839 
4840  /* properties */
4841  float border;
4842  float rounding;
4843  struct nk_vec2 padding;
4844  struct nk_vec2 image_padding;
4845  struct nk_vec2 touch_padding;
4846 
4847  /* optional user callbacks */
4851 };
4852 
4854  /* background */
4855  struct nk_style_item normal;
4856  struct nk_style_item hover;
4857  struct nk_style_item active;
4858  struct nk_color border_color;
4859 
4860  /* cursor */
4862  struct nk_style_item cursor_hover;
4863 
4864  /* text */
4865  struct nk_color text_normal;
4866  struct nk_color text_hover;
4867  struct nk_color text_active;
4868  struct nk_color text_background;
4870 
4871  /* properties */
4872  struct nk_vec2 padding;
4873  struct nk_vec2 touch_padding;
4874  float spacing;
4875  float border;
4876 
4877  /* optional user callbacks */
4881 };
4882 
4884  /* background (inactive) */
4885  struct nk_style_item normal;
4886  struct nk_style_item hover;
4887  struct nk_style_item pressed;
4888 
4889  /* background (active) */
4891  struct nk_style_item hover_active;
4893 
4894  /* text color (inactive) */
4895  struct nk_color text_normal;
4896  struct nk_color text_hover;
4897  struct nk_color text_pressed;
4898 
4899  /* text color (active) */
4901  struct nk_color text_hover_active;
4903  struct nk_color text_background;
4905 
4906  /* properties */
4907  float rounding;
4908  struct nk_vec2 padding;
4909  struct nk_vec2 touch_padding;
4910  struct nk_vec2 image_padding;
4911 
4912  /* optional user callbacks */
4916 };
4917 
4919  /* background */
4920  struct nk_style_item normal;
4921  struct nk_style_item hover;
4922  struct nk_style_item active;
4923  struct nk_color border_color;
4924 
4925  /* background bar */
4926  struct nk_color bar_normal;
4927  struct nk_color bar_hover;
4928  struct nk_color bar_active;
4929  struct nk_color bar_filled;
4930 
4931  /* cursor */
4933  struct nk_style_item cursor_hover;
4935 
4936  /* properties */
4937  float border;
4938  float rounding;
4939  float bar_height;
4940  struct nk_vec2 padding;
4941  struct nk_vec2 spacing;
4942  struct nk_vec2 cursor_size;
4943 
4944  /* optional buttons */
4946  struct nk_style_button inc_button;
4947  struct nk_style_button dec_button;
4950 
4951  /* optional user callbacks */
4955 };
4956 
4958  /* background */
4959  struct nk_style_item normal;
4960  struct nk_style_item hover;
4961  struct nk_style_item active;
4962  struct nk_color border_color;
4963 
4964  /* cursor */
4966  struct nk_style_item cursor_hover;
4969 
4970  /* properties */
4971  float rounding;
4972  float border;
4975  struct nk_vec2 padding;
4976 
4977  /* optional user callbacks */
4981 };
4982 
4984  /* background */
4985  struct nk_style_item normal;
4986  struct nk_style_item hover;
4987  struct nk_style_item active;
4988  struct nk_color border_color;
4989 
4990  /* cursor */
4992  struct nk_style_item cursor_hover;
4995 
4996  /* properties */
4997  float border;
4998  float rounding;
5001  struct nk_vec2 padding;
5002 
5003  /* optional buttons */
5005  struct nk_style_button inc_button;
5006  struct nk_style_button dec_button;
5009 
5010  /* optional user callbacks */
5014 };
5015 
5017  /* background */
5018  struct nk_style_item normal;
5019  struct nk_style_item hover;
5020  struct nk_style_item active;
5021  struct nk_color border_color;
5023 
5024  /* cursor */
5025  struct nk_color cursor_normal;
5026  struct nk_color cursor_hover;
5028  struct nk_color cursor_text_hover;
5029 
5030  /* text (unselected) */
5031  struct nk_color text_normal;
5032  struct nk_color text_hover;
5033  struct nk_color text_active;
5034 
5035  /* text (selected) */
5036  struct nk_color selected_normal;
5037  struct nk_color selected_hover;
5040 
5041  /* properties */
5042  float border;
5043  float rounding;
5045  struct nk_vec2 scrollbar_size;
5046  struct nk_vec2 padding;
5048 };
5049 
5051  /* background */
5052  struct nk_style_item normal;
5053  struct nk_style_item hover;
5054  struct nk_style_item active;
5055  struct nk_color border_color;
5056 
5057  /* text */
5058  struct nk_color label_normal;
5059  struct nk_color label_hover;
5060  struct nk_color label_active;
5061 
5062  /* symbols */
5063  enum nk_symbol_type sym_left;
5065 
5066  /* properties */
5067  float border;
5068  float rounding;
5069  struct nk_vec2 padding;
5070 
5071  struct nk_style_edit edit;
5072  struct nk_style_button inc_button;
5073  struct nk_style_button dec_button;
5074 
5075  /* optional user callbacks */
5079 };
5080 
5082  /* colors */
5083  struct nk_style_item background;
5084  struct nk_color border_color;
5085  struct nk_color selected_color;
5086  struct nk_color color;
5087 
5088  /* properties */
5089  float border;
5090  float rounding;
5091  struct nk_vec2 padding;
5092 };
5093 
5095  /* background */
5096  struct nk_style_item normal;
5097  struct nk_style_item hover;
5098  struct nk_style_item active;
5099  struct nk_color border_color;
5100 
5101  /* label */
5102  struct nk_color label_normal;
5103  struct nk_color label_hover;
5104  struct nk_color label_active;
5105 
5106  /* symbol */
5107  struct nk_color symbol_normal;
5108  struct nk_color symbol_hover;
5109  struct nk_color symbol_active;
5110 
5111  /* button */
5112  struct nk_style_button button;
5116 
5117  /* properties */
5118  float border;
5119  float rounding;
5120  struct nk_vec2 content_padding;
5121  struct nk_vec2 button_padding;
5122  struct nk_vec2 spacing;
5123 };
5124 
5126  /* background */
5127  struct nk_style_item background;
5128  struct nk_color border_color;
5129  struct nk_color text;
5130 
5131  /* button */
5138 
5139  /* properties */
5140  float border;
5141  float rounding;
5142  float indent;
5143  struct nk_vec2 padding;
5144  struct nk_vec2 spacing;
5145 };
5146 
5150 };
5152  /* background */
5153  struct nk_style_item normal;
5154  struct nk_style_item hover;
5155  struct nk_style_item active;
5156 
5157  /* button */
5163 
5164  /* title */
5165  struct nk_color label_normal;
5166  struct nk_color label_hover;
5167  struct nk_color label_active;
5168 
5169  /* properties */
5171  struct nk_vec2 padding;
5172  struct nk_vec2 label_padding;
5173  struct nk_vec2 spacing;
5174 };
5175 
5179  struct nk_color background;
5180 
5181  struct nk_color border_color;
5185  struct nk_color menu_border_color;
5188  struct nk_style_item scaler;
5189 
5190  float border;
5198 
5199  float rounding;
5200  struct nk_vec2 spacing;
5201  struct nk_vec2 scrollbar_size;
5202  struct nk_vec2 min_size;
5203 
5204  struct nk_vec2 padding;
5205  struct nk_vec2 group_padding;
5206  struct nk_vec2 popup_padding;
5207  struct nk_vec2 combo_padding;
5208  struct nk_vec2 contextual_padding;
5209  struct nk_vec2 menu_padding;
5210  struct nk_vec2 tooltip_padding;
5211 };
5212 
5213 struct nk_style {
5214  const struct nk_user_font *font;
5216  const struct nk_cursor *cursor_active;
5219 
5220  struct nk_style_text text;
5221  struct nk_style_button button;
5224  struct nk_style_toggle option;
5225  struct nk_style_toggle checkbox;
5227  struct nk_style_slider slider;
5228  struct nk_style_progress progress;
5229  struct nk_style_property property;
5230  struct nk_style_edit edit;
5231  struct nk_style_chart chart;
5232  struct nk_style_scrollbar scrollh;
5233  struct nk_style_scrollbar scrollv;
5234  struct nk_style_tab tab;
5235  struct nk_style_combo combo;
5236  struct nk_style_window window;
5237 };
5238 
5242 
5243 /*==============================================================
5244  * PANEL
5245  * =============================================================*/
5246 #ifndef NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS
5247 #define NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS 16
5248 #endif
5249 #ifndef NK_CHART_MAX_SLOT
5250 #define NK_CHART_MAX_SLOT 4
5251 #endif
5252 
5262 };
5267 };
5268 
5270  enum nk_chart_type type;
5271  struct nk_color color;
5272  struct nk_color highlight;
5273  float min, max, range;
5274  int count;
5275  struct nk_vec2 last;
5276  int index;
5277 };
5278 
5279 struct nk_chart {
5280  int slot;
5281  float x, y, w, h;
5283 };
5284 
5296 };
5299  int index;
5300  float height;
5301  float min_height;
5302  int columns;
5303  const float *ratio;
5304  float item_width;
5307  float filled;
5308  struct nk_rect item;
5311 };
5312 
5318  int active;
5319 };
5320 
5322  float x, y, w, h;
5323  struct nk_scroll offset;
5324 };
5325 
5326 struct nk_panel {
5327  enum nk_panel_type type;
5329  struct nk_rect bounds;
5332  float at_x, at_y, max_x;
5335  float border;
5336  unsigned int has_scrolling;
5337  struct nk_rect clip;
5338  struct nk_menu_state menu;
5339  struct nk_row_layout row;
5340  struct nk_chart chart;
5342  struct nk_panel *parent;
5343 };
5344 
5345 /*==============================================================
5346  * WINDOW
5347  * =============================================================*/
5348 #ifndef NK_WINDOW_MAX_NAME
5349 #define NK_WINDOW_MAX_NAME 64
5350 #endif
5351 
5352 struct nk_table;
5356  /* special window type growing up in height while being filled to a certain maximum height */
5358  /* sets window widgets into a read only mode and does not allow input changes */
5360  /* prevents all interaction caused by input to either window or widgets inside */
5362  /* Hides window and stops any window interaction and drawing */
5364  /* Directly closes and frees the window at the end of the frame */
5366  /* marks the window as minimized */
5368  /* Removes read only mode at the end of the window */
5369 };
5370 
5372  struct nk_window *win;
5373  enum nk_panel_type type;
5374  struct nk_popup_buffer buf;
5376  int active;
5377  unsigned combo_count;
5378  unsigned con_count, con_old;
5379  unsigned active_con;
5380  struct nk_rect header;
5381 };
5382 
5385  unsigned int seq;
5386  unsigned int old;
5387  int active, prev;
5388  int cursor;
5390  int sel_end;
5391  struct nk_scroll scrollbar;
5392  unsigned char mode;
5393  unsigned char single_line;
5394 };
5395 
5397  int active, prev;
5399  int length;
5400  int cursor;
5404  unsigned int seq;
5405  unsigned int old;
5406  int state;
5407 };
5408 
5409 struct nk_window {
5410  unsigned int seq;
5414 
5415  struct nk_rect bounds;
5416  struct nk_scroll scrollbar;
5417  struct nk_command_buffer buffer;
5418  struct nk_panel *layout;
5420 
5421  /* persistent widget state */
5422  struct nk_property_state property;
5423  struct nk_popup_state popup;
5424  struct nk_edit_state edit;
5425  unsigned int scrolled;
5426 
5427  struct nk_table *tables;
5428  unsigned int table_count;
5429 
5430  /* window list hooks */
5431  struct nk_window *next;
5432  struct nk_window *prev;
5434 };
5435 
5436 /*==============================================================
5437  * STACK
5438  * =============================================================*/
5439 /* The style modifier stack can be used to temporarily change a
5440  * property inside `nk_style`. For example if you want a special
5441  * red button you can temporarily push the old button color onto a stack
5442  * draw the button with a red color and then you just pop the old color
5443  * back from the stack:
5444  *
5445  * nk_style_push_style_item(ctx, &ctx->style.button.normal, nk_style_item_color(nk_rgb(255,0,0)));
5446  * nk_style_push_style_item(ctx, &ctx->style.button.hover, nk_style_item_color(nk_rgb(255,0,0)));
5447  * nk_style_push_style_item(ctx, &ctx->style.button.active, nk_style_item_color(nk_rgb(255,0,0)));
5448  * nk_style_push_vec2(ctx, &cx->style.button.padding, nk_vec2(2,2));
5449  *
5450  * nk_button(...);
5451  *
5452  * nk_style_pop_style_item(ctx);
5453  * nk_style_pop_style_item(ctx);
5454  * nk_style_pop_style_item(ctx);
5455  * nk_style_pop_vec2(ctx);
5456  *
5457  * Nuklear has a stack for style_items, float properties, vector properties,
5458  * flags, colors, fonts and for button_behavior. Each has it's own fixed size stack
5459  * which can be changed at compile time.
5460  */
5461 #ifndef NK_BUTTON_BEHAVIOR_STACK_SIZE
5462 #define NK_BUTTON_BEHAVIOR_STACK_SIZE 8
5463 #endif
5464 
5465 #ifndef NK_FONT_STACK_SIZE
5466 #define NK_FONT_STACK_SIZE 8
5467 #endif
5468 
5469 #ifndef NK_STYLE_ITEM_STACK_SIZE
5470 #define NK_STYLE_ITEM_STACK_SIZE 16
5471 #endif
5472 
5473 #ifndef NK_FLOAT_STACK_SIZE
5474 #define NK_FLOAT_STACK_SIZE 32
5475 #endif
5476 
5477 #ifndef NK_VECTOR_STACK_SIZE
5478 #define NK_VECTOR_STACK_SIZE 16
5479 #endif
5480 
5481 #ifndef NK_FLAGS_STACK_SIZE
5482 #define NK_FLAGS_STACK_SIZE 32
5483 #endif
5484 
5485 #ifndef NK_COLOR_STACK_SIZE
5486 #define NK_COLOR_STACK_SIZE 32
5487 #endif
5488 
5489 #define NK_CONFIGURATION_STACK_TYPE(prefix, name, type)\
5490  struct nk_config_stack_##name##_element {\
5491  prefix##_##type *address;\
5492  prefix##_##type old_value;\
5493  }
5494 #define NK_CONFIG_STACK(type,size)\
5495  struct nk_config_stack_##type {\
5496  int head;\
5497  struct nk_config_stack_##type##_element elements[size];\
5498  }
5499 
5500 #define nk_float float
5501 NK_CONFIGURATION_STACK_TYPE(struct nk, style_item, style_item);
5503 NK_CONFIGURATION_STACK_TYPE(struct nk, vec2, vec2);
5505 NK_CONFIGURATION_STACK_TYPE(struct nk, color, color);
5506 NK_CONFIGURATION_STACK_TYPE(const struct nk, user_font, user_font*);
5507 NK_CONFIGURATION_STACK_TYPE(enum nk, button_behavior, button_behavior);
5508 
5516 
5518  struct nk_config_stack_style_item style_items;
5519  struct nk_config_stack_float floats;
5520  struct nk_config_stack_vec2 vectors;
5521  struct nk_config_stack_flags flags;
5522  struct nk_config_stack_color colors;
5523  struct nk_config_stack_user_font fonts;
5524  struct nk_config_stack_button_behavior button_behaviors;
5525 };
5526 
5527 /*==============================================================
5528  * CONTEXT
5529  * =============================================================*/
5530 #define NK_VALUE_PAGE_CAPACITY \
5531  (((NK_MAX(sizeof(struct nk_window),sizeof(struct nk_panel)) / sizeof(nk_uint))) / 2)
5532 
5533 struct nk_table {
5534  unsigned int seq;
5535  unsigned int size;
5538  struct nk_table *next, *prev;
5539 };
5540 
5542  struct nk_table tbl;
5543  struct nk_panel pan;
5544  struct nk_window win;
5545 };
5546 
5548  union nk_page_data data;
5551 };
5552 
5553 struct nk_page {
5554  unsigned int size;
5555  struct nk_page *next;
5556  struct nk_page_element win[1];
5557 };
5558 
5559 struct nk_pool {
5560  struct nk_allocator alloc;
5561  enum nk_allocation_type type;
5562  unsigned int page_count;
5563  struct nk_page *pages;
5565  unsigned capacity;
5568 };
5569 
5570 struct nk_context {
5571 /* public: can be accessed freely */
5572  struct nk_input input;
5573  struct nk_style style;
5574  struct nk_buffer memory;
5575  struct nk_clipboard clip;
5580 
5581 /* private:
5582  should only be accessed if you
5583  know what you are doing */
5584 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
5585  struct nk_draw_list draw_list;
5586 #endif
5587 #ifdef NK_INCLUDE_COMMAND_USERDATA
5588  nk_handle userdata;
5589 #endif
5590  /* text editor objects are quite big because of an internal
5591  * undo/redo stack. Therefore it does not make sense to have one for
5592  * each window for temporary use cases, so I only provide *one* instance
5593  * for all windows. This works because the content is cleared anyway */
5594  struct nk_text_edit text_edit;
5595  /* draw buffer used for overlay drawing operation like cursor */
5596  struct nk_command_buffer overlay;
5597 
5598  /* windows */
5599  int build;
5601  struct nk_pool pool;
5602  struct nk_window *begin;
5603  struct nk_window *end;
5607  unsigned int count;
5608  unsigned int seq;
5609 };
5610 
5611 /* ==============================================================
5612  * MATH
5613  * =============================================================== */
5614 #define NK_PI 3.141592654f
5615 #define NK_UTF_INVALID 0xFFFD
5616 #define NK_MAX_FLOAT_PRECISION 2
5617 
5618 #define NK_UNUSED(x) ((void)(x))
5619 #define NK_SATURATE(x) (NK_MAX(0, NK_MIN(1.0f, x)))
5620 #define NK_LEN(a) (sizeof(a)/sizeof(a)[0])
5621 #define NK_ABS(a) (((a) < 0) ? -(a) : (a))
5622 #define NK_BETWEEN(x, a, b) ((a) <= (x) && (x) < (b))
5623 #define NK_INBOX(px, py, x, y, w, h)\
5624  (NK_BETWEEN(px,x,x+w) && NK_BETWEEN(py,y,y+h))
5625 #define NK_INTERSECT(x0, y0, w0, h0, x1, y1, w1, h1) \
5626  (!(((x1 > (x0 + w0)) || ((x1 + w1) < x0) || (y1 > (y0 + h0)) || (y1 + h1) < y0)))
5627 #define NK_CONTAINS(x, y, w, h, bx, by, bw, bh)\
5628  (NK_INBOX(x,y, bx, by, bw, bh) && NK_INBOX(x+w,y+h, bx, by, bw, bh))
5629 
5630 #define nk_vec2_sub(a, b) nk_vec2((a).x - (b).x, (a).y - (b).y)
5631 #define nk_vec2_add(a, b) nk_vec2((a).x + (b).x, (a).y + (b).y)
5632 #define nk_vec2_len_sqr(a) ((a).x*(a).x+(a).y*(a).y)
5633 #define nk_vec2_muls(a, t) nk_vec2((a).x * (t), (a).y * (t))
5634 
5635 #define nk_ptr_add(t, p, i) ((t*)((void*)((nk_byte*)(p) + (i))))
5636 #define nk_ptr_add_const(t, p, i) ((const t*)((const void*)((const nk_byte*)(p) + (i))))
5637 #define nk_zero_struct(s) nk_zero(&s, sizeof(s))
5638 
5639 /* ==============================================================
5640  * ALIGNMENT
5641  * =============================================================== */
5642 /* Pointer to Integer type conversion for pointer alignment */
5643 #if defined(__PTRDIFF_TYPE__) /* This case should work for GCC*/
5644 # define NK_UINT_TO_PTR(x) ((void*)(__PTRDIFF_TYPE__)(x))
5645 # define NK_PTR_TO_UINT(x) ((nk_size)(__PTRDIFF_TYPE__)(x))
5646 #elif !defined(__GNUC__) /* works for compilers other than LLVM */
5647 # define NK_UINT_TO_PTR(x) ((void*)&((char*)0)[x])
5648 # define NK_PTR_TO_UINT(x) ((nk_size)(((char*)x)-(char*)0))
5649 #elif defined(NK_USE_FIXED_TYPES) /* used if we have <stdint.h> */
5650 # define NK_UINT_TO_PTR(x) ((void*)(uintptr_t)(x))
5651 # define NK_PTR_TO_UINT(x) ((uintptr_t)(x))
5652 #else /* generates warning but works */
5653 # define NK_UINT_TO_PTR(x) ((void*)(x))
5654 # define NK_PTR_TO_UINT(x) ((nk_size)(x))
5655 #endif
5656 
5657 #define NK_ALIGN_PTR(x, mask)\
5658  (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x) + (mask-1)) & ~(mask-1))))
5659 #define NK_ALIGN_PTR_BACK(x, mask)\
5660  (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x)) & ~(mask-1))))
5661 
5662 #define NK_OFFSETOF(st,m) ((nk_ptr)&(((st*)0)->m))
5663 #define NK_CONTAINER_OF(ptr,type,member)\
5664  (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member)))
5665 
5666 #ifdef __cplusplus
5667 }
5668 #endif
5669 
5670 #ifdef __cplusplus
5671 template<typename T> struct nk_alignof;
5672 template<typename T, int size_diff> struct nk_helper{enum {value = size_diff};};
5673 template<typename T> struct nk_helper<T,0>{enum {value = nk_alignof<T>::value};};
5674 template<typename T> struct nk_alignof{struct Big {T x; char c;}; enum {
5675  diff = sizeof(Big) - sizeof(T), value = nk_helper<Big, diff>::value};};
5676 #define NK_ALIGNOF(t) (nk_alignof<t>::value)
5677 #elif defined(_MSC_VER)
5678 #define NK_ALIGNOF(t) (__alignof(t))
5679 #else
5680 #define NK_ALIGNOF(t) ((char*)(&((struct {char c; t _h;}*)0)->_h) - (char*)0)
5681 #endif
5682 
5683 #endif /* NK_NUKLEAR_H_ */
5684 
5685 #ifdef NK_IMPLEMENTATION
5686 
5687 #ifndef NK_INTERNAL_H
5688 #define NK_INTERNAL_H
5689 
5690 #ifndef NK_POOL_DEFAULT_CAPACITY
5691 #define NK_POOL_DEFAULT_CAPACITY 16
5692 #endif
5693 
5694 #ifndef NK_DEFAULT_COMMAND_BUFFER_SIZE
5695 #define NK_DEFAULT_COMMAND_BUFFER_SIZE (4*1024)
5696 #endif
5697 
5698 #ifndef NK_BUFFER_DEFAULT_INITIAL_SIZE
5699 #define NK_BUFFER_DEFAULT_INITIAL_SIZE (4*1024)
5700 #endif
5701 
5702 /* standard library headers */
5703 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
5704 #include <stdlib.h> /* malloc, free */
5705 #endif
5706 #ifdef NK_INCLUDE_STANDARD_IO
5707 #include <stdio.h> /* fopen, fclose,... */
5708 #endif
5709 #ifdef NK_INCLUDE_STANDARD_VARARGS
5710 #include <stdarg.h> /* valist, va_start, va_end, ... */
5711 #endif
5712 #ifndef NK_ASSERT
5713 #include <assert.h>
5714 #define NK_ASSERT(expr) assert(expr)
5715 #endif
5716 
5717 #ifndef NK_MEMSET
5718 #define NK_MEMSET nk_memset
5719 #endif
5720 #ifndef NK_MEMCPY
5721 #define NK_MEMCPY nk_memcopy
5722 #endif
5723 #ifndef NK_SQRT
5724 #define NK_SQRT nk_sqrt
5725 #endif
5726 #ifndef NK_SIN
5727 #define NK_SIN nk_sin
5728 #endif
5729 #ifndef NK_COS
5730 #define NK_COS nk_cos
5731 #endif
5732 #ifndef NK_STRTOD
5733 #define NK_STRTOD nk_strtod
5734 #endif
5735 #ifndef NK_DTOA
5736 #define NK_DTOA nk_dtoa
5737 #endif
5738 
5739 #define NK_DEFAULT (-1)
5740 
5741 #ifndef NK_VSNPRINTF
5742 /* If your compiler does support `vsnprintf` I would highly recommend
5743  * defining this to vsnprintf instead since `vsprintf` is basically
5744  * unbelievable unsafe and should *NEVER* be used. But I have to support
5745  * it since C89 only provides this unsafe version. */
5746  #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) ||\
5747  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
5748  (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) ||\
5749  (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) ||\
5750  defined(_ISOC99_SOURCE) || defined(_BSD_SOURCE)
5751  #define NK_VSNPRINTF(s,n,f,a) vsnprintf(s,n,f,a)
5752  #else
5753  #define NK_VSNPRINTF(s,n,f,a) vsprintf(s,f,a)
5754  #endif
5755 #endif
5756 
5757 #define NK_SCHAR_MIN (-127)
5758 #define NK_SCHAR_MAX 127
5759 #define NK_UCHAR_MIN 0
5760 #define NK_UCHAR_MAX 256
5761 #define NK_SSHORT_MIN (-32767)
5762 #define NK_SSHORT_MAX 32767
5763 #define NK_USHORT_MIN 0
5764 #define NK_USHORT_MAX 65535
5765 #define NK_SINT_MIN (-2147483647)
5766 #define NK_SINT_MAX 2147483647
5767 #define NK_UINT_MIN 0
5768 #define NK_UINT_MAX 4294967295u
5769 
5770 /* Make sure correct type size:
5771  * This will fire with a negative subscript error if the type sizes
5772  * are set incorrectly by the compiler, and compile out if not */
5773 NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void*));
5774 NK_STATIC_ASSERT(sizeof(nk_ptr) == sizeof(void*));
5775 NK_STATIC_ASSERT(sizeof(nk_flags) >= 4);
5776 NK_STATIC_ASSERT(sizeof(nk_rune) >= 4);
5777 NK_STATIC_ASSERT(sizeof(nk_ushort) == 2);
5778 NK_STATIC_ASSERT(sizeof(nk_short) == 2);
5779 NK_STATIC_ASSERT(sizeof(nk_uint) == 4);
5780 NK_STATIC_ASSERT(sizeof(nk_int) == 4);
5781 NK_STATIC_ASSERT(sizeof(nk_byte) == 1);
5782 
5783 NK_GLOBAL const struct nk_rect nk_null_rect = {-8192.0f, -8192.0f, 16384, 16384};
5784 #define NK_FLOAT_PRECISION 0.00000000000001
5785 
5786 NK_GLOBAL const struct nk_color nk_red = {255,0,0,255};
5787 NK_GLOBAL const struct nk_color nk_green = {0,255,0,255};
5788 NK_GLOBAL const struct nk_color nk_blue = {0,0,255,255};
5789 NK_GLOBAL const struct nk_color nk_white = {255,255,255,255};
5790 NK_GLOBAL const struct nk_color nk_black = {0,0,0,255};
5791 NK_GLOBAL const struct nk_color nk_yellow = {255,255,0,255};
5792 
5793 /* widget */
5794 #define nk_widget_state_reset(s)\
5795  if ((*(s)) & NK_WIDGET_STATE_MODIFIED)\
5796  (*(s)) = NK_WIDGET_STATE_INACTIVE|NK_WIDGET_STATE_MODIFIED;\
5797  else (*(s)) = NK_WIDGET_STATE_INACTIVE;
5798 
5799 /* math */
5800 NK_LIB float nk_inv_sqrt(float n);
5801 NK_LIB float nk_sqrt(float x);
5802 NK_LIB float nk_sin(float x);
5803 NK_LIB float nk_cos(float x);
5804 NK_LIB nk_uint nk_round_up_pow2(nk_uint v);
5805 NK_LIB struct nk_rect nk_shrink_rect(struct nk_rect r, float amount);
5806 NK_LIB struct nk_rect nk_pad_rect(struct nk_rect r, struct nk_vec2 pad);
5807 NK_LIB void nk_unify(struct nk_rect *clip, const struct nk_rect *a, float x0, float y0, float x1, float y1);
5808 NK_LIB double nk_pow(double x, int n);
5809 NK_LIB int nk_ifloord(double x);
5810 NK_LIB int nk_ifloorf(float x);
5811 NK_LIB int nk_iceilf(float x);
5812 NK_LIB int nk_log10(double n);
5813 
5814 /* util */
5815 enum {NK_DO_NOT_STOP_ON_NEW_LINE, NK_STOP_ON_NEW_LINE};
5816 NK_LIB int nk_is_lower(int c);
5817 NK_LIB int nk_is_upper(int c);
5818 NK_LIB int nk_to_upper(int c);
5819 NK_LIB int nk_to_lower(int c);
5820 NK_LIB void* nk_memcopy(void *dst, const void *src, nk_size n);
5821 NK_LIB void nk_memset(void *ptr, int c0, nk_size size);
5822 NK_LIB void nk_zero(void *ptr, nk_size size);
5823 NK_LIB char *nk_itoa(char *s, long n);
5824 NK_LIB int nk_string_float_limit(char *string, int prec);
5825 NK_LIB char *nk_dtoa(char *s, double n);
5826 NK_LIB int nk_text_clamp(const struct nk_user_font *font, const char *text, int text_len, float space, int *glyphs, float *text_width, nk_rune *sep_list, int sep_count);
5827 NK_LIB struct nk_vec2 nk_text_calculate_text_bounds(const struct nk_user_font *font, const char *begin, int byte_len, float row_height, const char **remaining, struct nk_vec2 *out_offset, int *glyphs, int op);
5828 #ifdef NK_INCLUDE_STANDARD_VARARGS
5829 NK_LIB int nk_strfmt(char *buf, int buf_size, const char *fmt, va_list args);
5830 #endif
5831 #ifdef NK_INCLUDE_STANDARD_IO
5832 NK_LIB char *nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc);
5833 #endif
5834 
5835 /* buffer */
5836 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
5837 NK_LIB void* nk_malloc(nk_handle unused, void *old,nk_size size);
5838 NK_LIB void nk_mfree(nk_handle unused, void *ptr);
5839 #endif
5840 NK_LIB void* nk_buffer_align(void *unaligned, nk_size align, nk_size *alignment, enum nk_buffer_allocation_type type);
5841 NK_LIB void* nk_buffer_alloc(struct nk_buffer *b, enum nk_buffer_allocation_type type, nk_size size, nk_size align);
5842 NK_LIB void* nk_buffer_realloc(struct nk_buffer *b, nk_size capacity, nk_size *size);
5843 
5844 /* draw */
5845 NK_LIB void nk_command_buffer_init(struct nk_command_buffer *cb, struct nk_buffer *b, enum nk_command_clipping clip);
5846 NK_LIB void nk_command_buffer_reset(struct nk_command_buffer *b);
5847 NK_LIB void* nk_command_buffer_push(struct nk_command_buffer* b, enum nk_command_type t, nk_size size);
5848 NK_LIB void nk_draw_symbol(struct nk_command_buffer *out, enum nk_symbol_type type, struct nk_rect content, struct nk_color background, struct nk_color foreground, float border_width, const struct nk_user_font *font);
5849 
5850 /* buffering */
5851 NK_LIB void nk_start_buffer(struct nk_context *ctx, struct nk_command_buffer *b);
5852 NK_LIB void nk_start(struct nk_context *ctx, struct nk_window *win);
5853 NK_LIB void nk_start_popup(struct nk_context *ctx, struct nk_window *win);
5854 NK_LIB void nk_finish_popup(struct nk_context *ctx, struct nk_window*);
5855 NK_LIB void nk_finish_buffer(struct nk_context *ctx, struct nk_command_buffer *b);
5856 NK_LIB void nk_finish(struct nk_context *ctx, struct nk_window *w);
5857 NK_LIB void nk_build(struct nk_context *ctx);
5858 
5859 /* text editor */
5860 NK_LIB void nk_textedit_clear_state(struct nk_text_edit *state, enum nk_text_edit_type type, nk_plugin_filter filter);
5861 NK_LIB void nk_textedit_click(struct nk_text_edit *state, float x, float y, const struct nk_user_font *font, float row_height);
5862 NK_LIB void nk_textedit_drag(struct nk_text_edit *state, float x, float y, const struct nk_user_font *font, float row_height);
5863 NK_LIB void nk_textedit_key(struct nk_text_edit *state, enum nk_keys key, int shift_mod, const struct nk_user_font *font, float row_height);
5864 
5865 /* window */
5866 enum nk_window_insert_location {
5867  NK_INSERT_BACK, /* inserts window into the back of list (front of screen) */
5868  NK_INSERT_FRONT /* inserts window into the front of list (back of screen) */
5869 };
5870 NK_LIB void *nk_create_window(struct nk_context *ctx);
5871 NK_LIB void nk_remove_window(struct nk_context*, struct nk_window*);
5872 NK_LIB void nk_free_window(struct nk_context *ctx, struct nk_window *win);
5873 NK_LIB struct nk_window *nk_find_window(struct nk_context *ctx, nk_hash hash, const char *name);
5874 NK_LIB void nk_insert_window(struct nk_context *ctx, struct nk_window *win, enum nk_window_insert_location loc);
5875 
5876 /* pool */
5877 NK_LIB void nk_pool_init(struct nk_pool *pool, struct nk_allocator *alloc, unsigned int capacity);
5878 NK_LIB void nk_pool_free(struct nk_pool *pool);
5879 NK_LIB void nk_pool_init_fixed(struct nk_pool *pool, void *memory, nk_size size);
5880 NK_LIB struct nk_page_element *nk_pool_alloc(struct nk_pool *pool);
5881 
5882 /* page-element */
5883 NK_LIB struct nk_page_element* nk_create_page_element(struct nk_context *ctx);
5884 NK_LIB void nk_link_page_element_into_freelist(struct nk_context *ctx, struct nk_page_element *elem);
5885 NK_LIB void nk_free_page_element(struct nk_context *ctx, struct nk_page_element *elem);
5886 
5887 /* table */
5888 NK_LIB struct nk_table* nk_create_table(struct nk_context *ctx);
5889 NK_LIB void nk_remove_table(struct nk_window *win, struct nk_table *tbl);
5890 NK_LIB void nk_free_table(struct nk_context *ctx, struct nk_table *tbl);
5891 NK_LIB void nk_push_table(struct nk_window *win, struct nk_table *tbl);
5892 NK_LIB nk_uint *nk_add_value(struct nk_context *ctx, struct nk_window *win, nk_hash name, nk_uint value);
5893 NK_LIB nk_uint *nk_find_value(struct nk_window *win, nk_hash name);
5894 
5895 /* panel */
5896 NK_LIB void *nk_create_panel(struct nk_context *ctx);
5897 NK_LIB void nk_free_panel(struct nk_context*, struct nk_panel *pan);
5898 NK_LIB int nk_panel_has_header(nk_flags flags, const char *title);
5899 NK_LIB struct nk_vec2 nk_panel_get_padding(const struct nk_style *style, enum nk_panel_type type);
5900 NK_LIB float nk_panel_get_border(const struct nk_style *style, nk_flags flags, enum nk_panel_type type);
5901 NK_LIB struct nk_color nk_panel_get_border_color(const struct nk_style *style, enum nk_panel_type type);
5902 NK_LIB int nk_panel_is_sub(enum nk_panel_type type);
5903 NK_LIB int nk_panel_is_nonblock(enum nk_panel_type type);
5904 NK_LIB int nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type panel_type);
5905 NK_LIB void nk_panel_end(struct nk_context *ctx);
5906 
5907 /* layout */
5908 NK_LIB float nk_layout_row_calculate_usable_space(const struct nk_style *style, enum nk_panel_type type, float total_space, int columns);
5909 NK_LIB void nk_panel_layout(const struct nk_context *ctx, struct nk_window *win, float height, int cols);
5910 NK_LIB void nk_row_layout(struct nk_context *ctx, enum nk_layout_format fmt, float height, int cols, int width);
5911 NK_LIB void nk_panel_alloc_row(const struct nk_context *ctx, struct nk_window *win);
5912 NK_LIB void nk_layout_widget_space(struct nk_rect *bounds, const struct nk_context *ctx, struct nk_window *win, int modify);
5913 NK_LIB void nk_panel_alloc_space(struct nk_rect *bounds, const struct nk_context *ctx);
5914 NK_LIB void nk_layout_peek(struct nk_rect *bounds, struct nk_context *ctx);
5915 
5916 /* popup */
5917 NK_LIB int nk_nonblock_begin(struct nk_context *ctx, nk_flags flags, struct nk_rect body, struct nk_rect header, enum nk_panel_type panel_type);
5918 
5919 /* text */
5920 struct nk_text {
5921  struct nk_vec2 padding;
5922  struct nk_color background;
5923  struct nk_color text;
5924 };
5925 NK_LIB void nk_widget_text(struct nk_command_buffer *o, struct nk_rect b, const char *string, int len, const struct nk_text *t, nk_flags a, const struct nk_user_font *f);
5926 NK_LIB void nk_widget_text_wrap(struct nk_command_buffer *o, struct nk_rect b, const char *string, int len, const struct nk_text *t, const struct nk_user_font *f);
5927 
5928 /* button */
5929 NK_LIB int nk_button_behavior(nk_flags *state, struct nk_rect r, const struct nk_input *i, enum nk_button_behavior behavior);
5930 NK_LIB const struct nk_style_item* nk_draw_button(struct nk_command_buffer *out, const struct nk_rect *bounds, nk_flags state, const struct nk_style_button *style);
5931 NK_LIB int nk_do_button(nk_flags *state, struct nk_command_buffer *out, struct nk_rect r, const struct nk_style_button *style, const struct nk_input *in, enum nk_button_behavior behavior, struct nk_rect *content);
5932 NK_LIB void nk_draw_button_text(struct nk_command_buffer *out, const struct nk_rect *bounds, const struct nk_rect *content, nk_flags state, const struct nk_style_button *style, const char *txt, int len, nk_flags text_alignment, const struct nk_user_font *font);
5933 NK_LIB int nk_do_button_text(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, const char *string, int len, nk_flags align, enum nk_button_behavior behavior, const struct nk_style_button *style, const struct nk_input *in, const struct nk_user_font *font);
5934 NK_LIB void nk_draw_button_symbol(struct nk_command_buffer *out, const struct nk_rect *bounds, const struct nk_rect *content, nk_flags state, const struct nk_style_button *style, enum nk_symbol_type type, const struct nk_user_font *font);
5935 NK_LIB int nk_do_button_symbol(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, enum nk_symbol_type symbol, enum nk_button_behavior behavior, const struct nk_style_button *style, const struct nk_input *in, const struct nk_user_font *font);
5936 NK_LIB void nk_draw_button_image(struct nk_command_buffer *out, const struct nk_rect *bounds, const struct nk_rect *content, nk_flags state, const struct nk_style_button *style, const struct nk_image *img);
5937 NK_LIB int nk_do_button_image(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, struct nk_image img, enum nk_button_behavior b, const struct nk_style_button *style, const struct nk_input *in);
5938 NK_LIB void nk_draw_button_text_symbol(struct nk_command_buffer *out, const struct nk_rect *bounds, const struct nk_rect *label, const struct nk_rect *symbol, nk_flags state, const struct nk_style_button *style, const char *str, int len, enum nk_symbol_type type, const struct nk_user_font *font);
5939 NK_LIB int nk_do_button_text_symbol(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, enum nk_symbol_type symbol, const char *str, int len, nk_flags align, enum nk_button_behavior behavior, const struct nk_style_button *style, const struct nk_user_font *font, const struct nk_input *in);
5940 NK_LIB void nk_draw_button_text_image(struct nk_command_buffer *out, const struct nk_rect *bounds, const struct nk_rect *label, const struct nk_rect *image, nk_flags state, const struct nk_style_button *style, const char *str, int len, const struct nk_user_font *font, const struct nk_image *img);
5941 NK_LIB int nk_do_button_text_image(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, struct nk_image img, const char* str, int len, nk_flags align, enum nk_button_behavior behavior, const struct nk_style_button *style, const struct nk_user_font *font, const struct nk_input *in);
5942 
5943 /* toggle */
5944 enum nk_toggle_type {
5945  NK_TOGGLE_CHECK,
5946  NK_TOGGLE_OPTION
5947 };
5948 NK_LIB int nk_toggle_behavior(const struct nk_input *in, struct nk_rect select, nk_flags *state, int active);
5949 NK_LIB void nk_draw_checkbox(struct nk_command_buffer *out, nk_flags state, const struct nk_style_toggle *style, int active, const struct nk_rect *label, const struct nk_rect *selector, const struct nk_rect *cursors, const char *string, int len, const struct nk_user_font *font);
5950 NK_LIB void nk_draw_option(struct nk_command_buffer *out, nk_flags state, const struct nk_style_toggle *style, int active, const struct nk_rect *label, const struct nk_rect *selector, const struct nk_rect *cursors, const char *string, int len, const struct nk_user_font *font);
5951 NK_LIB int nk_do_toggle(nk_flags *state, struct nk_command_buffer *out, struct nk_rect r, int *active, const char *str, int len, enum nk_toggle_type type, const struct nk_style_toggle *style, const struct nk_input *in, const struct nk_user_font *font);
5952 
5953 /* progress */
5954 NK_LIB nk_size nk_progress_behavior(nk_flags *state, struct nk_input *in, struct nk_rect r, struct nk_rect cursor, nk_size max, nk_size value, int modifiable);
5955 NK_LIB void nk_draw_progress(struct nk_command_buffer *out, nk_flags state, const struct nk_style_progress *style, const struct nk_rect *bounds, const struct nk_rect *scursor, nk_size value, nk_size max);
5956 NK_LIB nk_size nk_do_progress(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, nk_size value, nk_size max, int modifiable, const struct nk_style_progress *style, struct nk_input *in);
5957 
5958 /* slider */
5959 NK_LIB float nk_slider_behavior(nk_flags *state, struct nk_rect *logical_cursor, struct nk_rect *visual_cursor, struct nk_input *in, struct nk_rect bounds, float slider_min, float slider_max, float slider_value, float slider_step, float slider_steps);
5960 NK_LIB void nk_draw_slider(struct nk_command_buffer *out, nk_flags state, const struct nk_style_slider *style, const struct nk_rect *bounds, const struct nk_rect *visual_cursor, float min, float value, float max);
5961 NK_LIB float nk_do_slider(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, float min, float val, float max, float step, const struct nk_style_slider *style, struct nk_input *in, const struct nk_user_font *font);
5962 
5963 /* scrollbar */
5964 NK_LIB float nk_scrollbar_behavior(nk_flags *state, struct nk_input *in, int has_scrolling, const struct nk_rect *scroll, const struct nk_rect *cursor, const struct nk_rect *empty0, const struct nk_rect *empty1, float scroll_offset, float target, float scroll_step, enum nk_orientation o);
5965 NK_LIB void nk_draw_scrollbar(struct nk_command_buffer *out, nk_flags state, const struct nk_style_scrollbar *style, const struct nk_rect *bounds, const struct nk_rect *scroll);
5966 NK_LIB float nk_do_scrollbarv(nk_flags *state, struct nk_command_buffer *out, struct nk_rect scroll, int has_scrolling, float offset, float target, float step, float button_pixel_inc, const struct nk_style_scrollbar *style, struct nk_input *in, const struct nk_user_font *font);
5967 NK_LIB float nk_do_scrollbarh(nk_flags *state, struct nk_command_buffer *out, struct nk_rect scroll, int has_scrolling, float offset, float target, float step, float button_pixel_inc, const struct nk_style_scrollbar *style, struct nk_input *in, const struct nk_user_font *font);
5968 
5969 /* selectable */
5970 NK_LIB void nk_draw_selectable(struct nk_command_buffer *out, nk_flags state, const struct nk_style_selectable *style, int active, const struct nk_rect *bounds, const struct nk_rect *icon, const struct nk_image *img, enum nk_symbol_type sym, const char *string, int len, nk_flags align, const struct nk_user_font *font);
5971 NK_LIB int nk_do_selectable(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, const char *str, int len, nk_flags align, int *value, const struct nk_style_selectable *style, const struct nk_input *in, const struct nk_user_font *font);
5972 NK_LIB int nk_do_selectable_image(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, const char *str, int len, nk_flags align, int *value, const struct nk_image *img, const struct nk_style_selectable *style, const struct nk_input *in, const struct nk_user_font *font);
5973 
5974 /* edit */
5975 NK_LIB void nk_edit_draw_text(struct nk_command_buffer *out, const struct nk_style_edit *style, float pos_x, float pos_y, float x_offset, const char *text, int byte_len, float row_height, const struct nk_user_font *font, struct nk_color background, struct nk_color foreground, int is_selected);
5976 NK_LIB nk_flags nk_do_edit(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, nk_flags flags, nk_plugin_filter filter, struct nk_text_edit *edit, const struct nk_style_edit *style, struct nk_input *in, const struct nk_user_font *font);
5977 
5978 /* color-picker */
5979 NK_LIB int nk_color_picker_behavior(nk_flags *state, const struct nk_rect *bounds, const struct nk_rect *matrix, const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar, struct nk_colorf *color, const struct nk_input *in);
5980 NK_LIB void nk_draw_color_picker(struct nk_command_buffer *o, const struct nk_rect *matrix, const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar, struct nk_colorf col);
5981 NK_LIB int nk_do_color_picker(nk_flags *state, struct nk_command_buffer *out, struct nk_colorf *col, enum nk_color_format fmt, struct nk_rect bounds, struct nk_vec2 padding, const struct nk_input *in, const struct nk_user_font *font);
5982 
5983 /* property */
5984 enum nk_property_status {
5985  NK_PROPERTY_DEFAULT,
5986  NK_PROPERTY_EDIT,
5987  NK_PROPERTY_DRAG
5988 };
5989 enum nk_property_filter {
5990  NK_FILTER_INT,
5991  NK_FILTER_FLOAT
5992 };
5993 enum nk_property_kind {
5994  NK_PROPERTY_INT,
5995  NK_PROPERTY_FLOAT,
5996  NK_PROPERTY_DOUBLE
5997 };
5998 union nk_property {
5999  int i;
6000  float f;
6001  double d;
6002 };
6003 struct nk_property_variant {
6004  enum nk_property_kind kind;
6005  union nk_property value;
6006  union nk_property min_value;
6007  union nk_property max_value;
6008  union nk_property step;
6009 };
6010 NK_LIB struct nk_property_variant nk_property_variant_int(int value, int min_value, int max_value, int step);
6011 NK_LIB struct nk_property_variant nk_property_variant_float(float value, float min_value, float max_value, float step);
6012 NK_LIB struct nk_property_variant nk_property_variant_double(double value, double min_value, double max_value, double step);
6013 
6014 NK_LIB void nk_drag_behavior(nk_flags *state, const struct nk_input *in, struct nk_rect drag, struct nk_property_variant *variant, float inc_per_pixel);
6015 NK_LIB void nk_property_behavior(nk_flags *ws, const struct nk_input *in, struct nk_rect property, struct nk_rect label, struct nk_rect edit, struct nk_rect empty, int *state, struct nk_property_variant *variant, float inc_per_pixel);
6016 NK_LIB void nk_draw_property(struct nk_command_buffer *out, const struct nk_style_property *style, const struct nk_rect *bounds, const struct nk_rect *label, nk_flags state, const char *name, int len, const struct nk_user_font *font);
6017 NK_LIB void nk_do_property(nk_flags *ws, struct nk_command_buffer *out, struct nk_rect property, const char *name, struct nk_property_variant *variant, float inc_per_pixel, char *buffer, int *len, int *state, int *cursor, int *select_begin, int *select_end, const struct nk_style_property *style, enum nk_property_filter filter, struct nk_input *in, const struct nk_user_font *font, struct nk_text_edit *text_edit, enum nk_button_behavior behavior);
6018 NK_LIB void nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant *variant, float inc_per_pixel, const enum nk_property_filter filter);
6019 
6020 #endif
6021 
6022 
6023 
6024 
6025 
6026 /* ===============================================================
6027  *
6028  * MATH
6029  *
6030  * ===============================================================*/
6031 /* Since nuklear is supposed to work on all systems providing floating point
6032  math without any dependencies I also had to implement my own math functions
6033  for sqrt, sin and cos. Since the actual highly accurate implementations for
6034  the standard library functions are quite complex and I do not need high
6035  precision for my use cases I use approximations.
6036 
6037  Sqrt
6038  ----
6039  For square root nuklear uses the famous fast inverse square root:
6040  https://en.wikipedia.org/wiki/Fast_inverse_square_root with
6041  slightly tweaked magic constant. While on today's hardware it is
6042  probably not faster it is still fast and accurate enough for
6043  nuklear's use cases. IMPORTANT: this requires float format IEEE 754
6044 
6045  Sine/Cosine
6046  -----------
6047  All constants inside both function are generated Remez's minimax
6048  approximations for value range 0...2*PI. The reason why I decided to
6049  approximate exactly that range is that nuklear only needs sine and
6050  cosine to generate circles which only requires that exact range.
6051  In addition I used Remez instead of Taylor for additional precision:
6052  www.lolengine.net/blog/2011/12/21/better-function-approximations.
6053 
6054  The tool I used to generate constants for both sine and cosine
6055  (it can actually approximate a lot more functions) can be
6056  found here: www.lolengine.net/wiki/oss/lolremez
6057 */
6058 NK_LIB float
6059 nk_inv_sqrt(float n)
6060 {
6061  float x2;
6062  const float threehalfs = 1.5f;
6063  union {nk_uint i; float f;} conv = {0};
6064  conv.f = n;
6065  x2 = n * 0.5f;
6066  conv.i = 0x5f375A84 - (conv.i >> 1);
6067  conv.f = conv.f * (threehalfs - (x2 * conv.f * conv.f));
6068  return conv.f;
6069 }
6070 NK_LIB float
6071 nk_sqrt(float x)
6072 {
6073  return x * nk_inv_sqrt(x);
6074 }
6075 NK_LIB float
6076 nk_sin(float x)
6077 {
6078  NK_STORAGE const float a0 = +1.91059300966915117e-31f;
6079  NK_STORAGE const float a1 = +1.00086760103908896f;
6080  NK_STORAGE const float a2 = -1.21276126894734565e-2f;
6081  NK_STORAGE const float a3 = -1.38078780785773762e-1f;
6082  NK_STORAGE const float a4 = -2.67353392911981221e-2f;
6083  NK_STORAGE const float a5 = +2.08026600266304389e-2f;
6084  NK_STORAGE const float a6 = -3.03996055049204407e-3f;
6085  NK_STORAGE const float a7 = +1.38235642404333740e-4f;
6086  return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*a7))))));
6087 }
6088 NK_LIB float
6089 nk_cos(float x)
6090 {
6091  /* New implementation. Also generated using lolremez. */
6092  /* Old version significantly deviated from expected results. */
6093  NK_STORAGE const float a0 = 9.9995999154986614e-1f;
6094  NK_STORAGE const float a1 = 1.2548995793001028e-3f;
6095  NK_STORAGE const float a2 = -5.0648546280678015e-1f;
6096  NK_STORAGE const float a3 = 1.2942246466519995e-2f;
6097  NK_STORAGE const float a4 = 2.8668384702547972e-2f;
6098  NK_STORAGE const float a5 = 7.3726485210586547e-3f;
6099  NK_STORAGE const float a6 = -3.8510875386947414e-3f;
6100  NK_STORAGE const float a7 = 4.7196604604366623e-4f;
6101  NK_STORAGE const float a8 = -1.8776444013090451e-5f;
6102  return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*(a7 + x*a8)))))));
6103 }
6105 nk_round_up_pow2(nk_uint v)
6106 {
6107  v--;
6108  v |= v >> 1;
6109  v |= v >> 2;
6110  v |= v >> 4;
6111  v |= v >> 8;
6112  v |= v >> 16;
6113  v++;
6114  return v;
6115 }
6116 NK_LIB double
6117 nk_pow(double x, int n)
6118 {
6119  /* check the sign of n */
6120  double r = 1;
6121  int plus = n >= 0;
6122  n = (plus) ? n : -n;
6123  while (n > 0) {
6124  if ((n & 1) == 1)
6125  r *= x;
6126  n /= 2;
6127  x *= x;
6128  }
6129  return plus ? r : 1.0 / r;
6130 }
6131 NK_LIB int
6132 nk_ifloord(double x)
6133 {
6134  x = (double)((int)x - ((x < 0.0) ? 1 : 0));
6135  return (int)x;
6136 }
6137 NK_LIB int
6138 nk_ifloorf(float x)
6139 {
6140  x = (float)((int)x - ((x < 0.0f) ? 1 : 0));
6141  return (int)x;
6142 }
6143 NK_LIB int
6144 nk_iceilf(float x)
6145 {
6146  if (x >= 0) {
6147  int i = (int)x;
6148  return (x > i) ? i+1: i;
6149  } else {
6150  int t = (int)x;
6151  float r = x - (float)t;
6152  return (r > 0.0f) ? t+1: t;
6153  }
6154 }
6155 NK_LIB int
6156 nk_log10(double n)
6157 {
6158  int neg;
6159  int ret;
6160  int exp = 0;
6161 
6162  neg = (n < 0) ? 1 : 0;
6163  ret = (neg) ? (int)-n : (int)n;
6164  while ((ret / 10) > 0) {
6165  ret /= 10;
6166  exp++;
6167  }
6168  if (neg) exp = -exp;
6169  return exp;
6170 }
6171 NK_API struct nk_rect
6172 nk_get_null_rect(void)
6173 {
6174  return nk_null_rect;
6175 }
6176 NK_API struct nk_rect
6177 nk_rect(float x, float y, float w, float h)
6178 {
6179  struct nk_rect r;
6180  r.x = x; r.y = y;
6181  r.w = w; r.h = h;
6182  return r;
6183 }
6184 NK_API struct nk_rect
6185 nk_recti(int x, int y, int w, int h)
6186 {
6187  struct nk_rect r;
6188  r.x = (float)x;
6189  r.y = (float)y;
6190  r.w = (float)w;
6191  r.h = (float)h;
6192  return r;
6193 }
6194 NK_API struct nk_rect
6195 nk_recta(struct nk_vec2 pos, struct nk_vec2 size)
6196 {
6197  return nk_rect(pos.x, pos.y, size.x, size.y);
6198 }
6199 NK_API struct nk_rect
6200 nk_rectv(const float *r)
6201 {
6202  return nk_rect(r[0], r[1], r[2], r[3]);
6203 }
6204 NK_API struct nk_rect
6205 nk_rectiv(const int *r)
6206 {
6207  return nk_recti(r[0], r[1], r[2], r[3]);
6208 }
6209 NK_API struct nk_vec2
6210 nk_rect_pos(struct nk_rect r)
6211 {
6212  struct nk_vec2 ret;
6213  ret.x = r.x; ret.y = r.y;
6214  return ret;
6215 }
6216 NK_API struct nk_vec2
6217 nk_rect_size(struct nk_rect r)
6218 {
6219  struct nk_vec2 ret;
6220  ret.x = r.w; ret.y = r.h;
6221  return ret;
6222 }
6223 NK_LIB struct nk_rect
6224 nk_shrink_rect(struct nk_rect r, float amount)
6225 {
6226  struct nk_rect res;
6227  r.w = NK_MAX(r.w, 2 * amount);
6228  r.h = NK_MAX(r.h, 2 * amount);
6229  res.x = r.x + amount;
6230  res.y = r.y + amount;
6231  res.w = r.w - 2 * amount;
6232  res.h = r.h - 2 * amount;
6233  return res;
6234 }
6235 NK_LIB struct nk_rect
6236 nk_pad_rect(struct nk_rect r, struct nk_vec2 pad)
6237 {
6238  r.w = NK_MAX(r.w, 2 * pad.x);
6239  r.h = NK_MAX(r.h, 2 * pad.y);
6240  r.x += pad.x; r.y += pad.y;
6241  r.w -= 2 * pad.x;
6242  r.h -= 2 * pad.y;
6243  return r;
6244 }
6245 NK_API struct nk_vec2
6246 nk_vec2(float x, float y)
6247 {
6248  struct nk_vec2 ret;
6249  ret.x = x; ret.y = y;
6250  return ret;
6251 }
6252 NK_API struct nk_vec2
6253 nk_vec2i(int x, int y)
6254 {
6255  struct nk_vec2 ret;
6256  ret.x = (float)x;
6257  ret.y = (float)y;
6258  return ret;
6259 }
6260 NK_API struct nk_vec2
6261 nk_vec2v(const float *v)
6262 {
6263  return nk_vec2(v[0], v[1]);
6264 }
6265 NK_API struct nk_vec2
6266 nk_vec2iv(const int *v)
6267 {
6268  return nk_vec2i(v[0], v[1]);
6269 }
6270 NK_LIB void
6271 nk_unify(struct nk_rect *clip, const struct nk_rect *a, float x0, float y0,
6272  float x1, float y1)
6273 {
6274  NK_ASSERT(a);
6275  NK_ASSERT(clip);
6276  clip->x = NK_MAX(a->x, x0);
6277  clip->y = NK_MAX(a->y, y0);
6278  clip->w = NK_MIN(a->x + a->w, x1) - clip->x;
6279  clip->h = NK_MIN(a->y + a->h, y1) - clip->y;
6280  clip->w = NK_MAX(0, clip->w);
6281  clip->h = NK_MAX(0, clip->h);
6282 }
6283 
6284 NK_API void
6285 nk_triangle_from_direction(struct nk_vec2 *result, struct nk_rect r,
6286  float pad_x, float pad_y, enum nk_heading direction)
6287 {
6288  float w_half, h_half;
6289  NK_ASSERT(result);
6290 
6291  r.w = NK_MAX(2 * pad_x, r.w);
6292  r.h = NK_MAX(2 * pad_y, r.h);
6293  r.w = r.w - 2 * pad_x;
6294  r.h = r.h - 2 * pad_y;
6295 
6296  r.x = r.x + pad_x;
6297  r.y = r.y + pad_y;
6298 
6299  w_half = r.w / 2.0f;
6300  h_half = r.h / 2.0f;
6301 
6302  if (direction == NK_UP) {
6303  result[0] = nk_vec2(r.x + w_half, r.y);
6304  result[1] = nk_vec2(r.x + r.w, r.y + r.h);
6305  result[2] = nk_vec2(r.x, r.y + r.h);
6306  } else if (direction == NK_RIGHT) {
6307  result[0] = nk_vec2(r.x, r.y);
6308  result[1] = nk_vec2(r.x + r.w, r.y + h_half);
6309  result[2] = nk_vec2(r.x, r.y + r.h);
6310  } else if (direction == NK_DOWN) {
6311  result[0] = nk_vec2(r.x, r.y);
6312  result[1] = nk_vec2(r.x + r.w, r.y);
6313  result[2] = nk_vec2(r.x + w_half, r.y + r.h);
6314  } else {
6315  result[0] = nk_vec2(r.x, r.y + h_half);
6316  result[1] = nk_vec2(r.x + r.w, r.y);
6317  result[2] = nk_vec2(r.x + r.w, r.y + r.h);
6318  }
6319 }
6320 
6321 
6322 
6323 
6324 
6325 /* ===============================================================
6326  *
6327  * UTIL
6328  *
6329  * ===============================================================*/
6330 NK_INTERN int nk_str_match_here(const char *regexp, const char *text);
6331 NK_INTERN int nk_str_match_star(int c, const char *regexp, const char *text);
6332 NK_LIB int nk_is_lower(int c) {return (c >= 'a' && c <= 'z') || (c >= 0xE0 && c <= 0xFF);}
6333 NK_LIB int nk_is_upper(int c){return (c >= 'A' && c <= 'Z') || (c >= 0xC0 && c <= 0xDF);}
6334 NK_LIB int nk_to_upper(int c) {return (c >= 'a' && c <= 'z') ? (c - ('a' - 'A')) : c;}
6335 NK_LIB int nk_to_lower(int c) {return (c >= 'A' && c <= 'Z') ? (c - ('a' + 'A')) : c;}
6336 
6337 NK_LIB void*
6338 nk_memcopy(void *dst0, const void *src0, nk_size length)
6339 {
6340  nk_ptr t;
6341  char *dst = (char*)dst0;
6342  const char *src = (const char*)src0;
6343  if (length == 0 || dst == src)
6344  goto done;
6345 
6346  #define nk_word int
6347  #define nk_wsize sizeof(nk_word)
6348  #define nk_wmask (nk_wsize-1)
6349  #define NK_TLOOP(s) if (t) NK_TLOOP1(s)
6350  #define NK_TLOOP1(s) do { s; } while (--t)
6351 
6352  if (dst < src) {
6353  t = (nk_ptr)src; /* only need low bits */
6354  if ((t | (nk_ptr)dst) & nk_wmask) {
6355  if ((t ^ (nk_ptr)dst) & nk_wmask || length < nk_wsize)
6356  t = length;
6357  else
6358  t = nk_wsize - (t & nk_wmask);
6359  length -= t;
6360  NK_TLOOP1(*dst++ = *src++);
6361  }
6362  t = length / nk_wsize;
6363  NK_TLOOP(*(nk_word*)(void*)dst = *(const nk_word*)(const void*)src;
6364  src += nk_wsize; dst += nk_wsize);
6365  t = length & nk_wmask;
6366  NK_TLOOP(*dst++ = *src++);
6367  } else {
6368  src += length;
6369  dst += length;
6370  t = (nk_ptr)src;
6371  if ((t | (nk_ptr)dst) & nk_wmask) {
6372  if ((t ^ (nk_ptr)dst) & nk_wmask || length <= nk_wsize)
6373  t = length;
6374  else
6375  t &= nk_wmask;
6376  length -= t;
6377  NK_TLOOP1(*--dst = *--src);
6378  }
6379  t = length / nk_wsize;
6380  NK_TLOOP(src -= nk_wsize; dst -= nk_wsize;
6381  *(nk_word*)(void*)dst = *(const nk_word*)(const void*)src);
6382  t = length & nk_wmask;
6383  NK_TLOOP(*--dst = *--src);
6384  }
6385  #undef nk_word
6386  #undef nk_wsize
6387  #undef nk_wmask
6388  #undef NK_TLOOP
6389  #undef NK_TLOOP1
6390 done:
6391  return (dst0);
6392 }
6393 NK_LIB void
6394 nk_memset(void *ptr, int c0, nk_size size)
6395 {
6396  #define nk_word unsigned
6397  #define nk_wsize sizeof(nk_word)
6398  #define nk_wmask (nk_wsize - 1)
6399  nk_byte *dst = (nk_byte*)ptr;
6400  unsigned c = 0;
6401  nk_size t = 0;
6402 
6403  if ((c = (nk_byte)c0) != 0) {
6404  c = (c << 8) | c; /* at least 16-bits */
6405  if (sizeof(unsigned int) > 2)
6406  c = (c << 16) | c; /* at least 32-bits*/
6407  }
6408 
6409  /* too small of a word count */
6410  dst = (nk_byte*)ptr;
6411  if (size < 3 * nk_wsize) {
6412  while (size--) *dst++ = (nk_byte)c0;
6413  return;
6414  }
6415 
6416  /* align destination */
6417  if ((t = NK_PTR_TO_UINT(dst) & nk_wmask) != 0) {
6418  t = nk_wsize -t;
6419  size -= t;
6420  do {
6421  *dst++ = (nk_byte)c0;
6422  } while (--t != 0);
6423  }
6424 
6425  /* fill word */
6426  t = size / nk_wsize;
6427  do {
6428  *(nk_word*)((void*)dst) = c;
6429  dst += nk_wsize;
6430  } while (--t != 0);
6431 
6432  /* fill trailing bytes */
6433  t = (size & nk_wmask);
6434  if (t != 0) {
6435  do {
6436  *dst++ = (nk_byte)c0;
6437  } while (--t != 0);
6438  }
6439 
6440  #undef nk_word
6441  #undef nk_wsize
6442  #undef nk_wmask
6443 }
6444 NK_LIB void
6445 nk_zero(void *ptr, nk_size size)
6446 {
6447  NK_ASSERT(ptr);
6448  NK_MEMSET(ptr, 0, size);
6449 }
6450 NK_API int
6451 nk_strlen(const char *str)
6452 {
6453  int siz = 0;
6454  NK_ASSERT(str);
6455  while (str && *str++ != '\0') siz++;
6456  return siz;
6457 }
6458 NK_API int
6459 nk_strtoi(const char *str, const char **endptr)
6460 {
6461  int neg = 1;
6462  const char *p = str;
6463  int value = 0;
6464 
6465  NK_ASSERT(str);
6466  if (!str) return 0;
6467 
6468  /* skip whitespace */
6469  while (*p == ' ') p++;
6470  if (*p == '-') {
6471  neg = -1;
6472  p++;
6473  }
6474  while (*p && *p >= '0' && *p <= '9') {
6475  value = value * 10 + (int) (*p - '0');
6476  p++;
6477  }
6478  if (endptr)
6479  *endptr = p;
6480  return neg*value;
6481 }
6482 NK_API double
6483 nk_strtod(const char *str, const char **endptr)
6484 {
6485  double m;
6486  double neg = 1.0;
6487  const char *p = str;
6488  double value = 0;
6489  double number = 0;
6490 
6491  NK_ASSERT(str);
6492  if (!str) return 0;
6493 
6494  /* skip whitespace */
6495  while (*p == ' ') p++;
6496  if (*p == '-') {
6497  neg = -1.0;
6498  p++;
6499  }
6500 
6501  while (*p && *p != '.' && *p != 'e') {
6502  value = value * 10.0 + (double) (*p - '0');
6503  p++;
6504  }
6505 
6506  if (*p == '.') {
6507  p++;
6508  for(m = 0.1; *p && *p != 'e'; p++ ) {
6509  value = value + (double) (*p - '0') * m;
6510  m *= 0.1;
6511  }
6512  }
6513  if (*p == 'e') {
6514  int i, pow, div;
6515  p++;
6516  if (*p == '-') {
6517  div = nk_true;
6518  p++;
6519  } else if (*p == '+') {
6520  div = nk_false;
6521  p++;
6522  } else div = nk_false;
6523 
6524  for (pow = 0; *p; p++)
6525  pow = pow * 10 + (int) (*p - '0');
6526 
6527  for (m = 1.0, i = 0; i < pow; i++)
6528  m *= 10.0;
6529 
6530  if (div)
6531  value /= m;
6532  else value *= m;
6533  }
6534  number = value * neg;
6535  if (endptr)
6536  *endptr = p;
6537  return number;
6538 }
6539 NK_API float
6540 nk_strtof(const char *str, const char **endptr)
6541 {
6542  float float_value;
6543  double double_value;
6544  double_value = NK_STRTOD(str, endptr);
6545  float_value = (float)double_value;
6546  return float_value;
6547 }
6548 NK_API int
6549 nk_stricmp(const char *s1, const char *s2)
6550 {
6551  nk_int c1,c2,d;
6552  do {
6553  c1 = *s1++;
6554  c2 = *s2++;
6555  d = c1 - c2;
6556  while (d) {
6557  if (c1 <= 'Z' && c1 >= 'A') {
6558  d += ('a' - 'A');
6559  if (!d) break;
6560  }
6561  if (c2 <= 'Z' && c2 >= 'A') {
6562  d -= ('a' - 'A');
6563  if (!d) break;
6564  }
6565  return ((d >= 0) << 1) - 1;
6566  }
6567  } while (c1);
6568  return 0;
6569 }
6570 NK_API int
6571 nk_stricmpn(const char *s1, const char *s2, int n)
6572 {
6573  int c1,c2,d;
6574  NK_ASSERT(n >= 0);
6575  do {
6576  c1 = *s1++;
6577  c2 = *s2++;
6578  if (!n--) return 0;
6579 
6580  d = c1 - c2;
6581  while (d) {
6582  if (c1 <= 'Z' && c1 >= 'A') {
6583  d += ('a' - 'A');
6584  if (!d) break;
6585  }
6586  if (c2 <= 'Z' && c2 >= 'A') {
6587  d -= ('a' - 'A');
6588  if (!d) break;
6589  }
6590  return ((d >= 0) << 1) - 1;
6591  }
6592  } while (c1);
6593  return 0;
6594 }
6595 NK_INTERN int
6596 nk_str_match_here(const char *regexp, const char *text)
6597 {
6598  if (regexp[0] == '\0')
6599  return 1;
6600  if (regexp[1] == '*')
6601  return nk_str_match_star(regexp[0], regexp+2, text);
6602  if (regexp[0] == '$' && regexp[1] == '\0')
6603  return *text == '\0';
6604  if (*text!='\0' && (regexp[0]=='.' || regexp[0]==*text))
6605  return nk_str_match_here(regexp+1, text+1);
6606  return 0;
6607 }
6608 NK_INTERN int
6609 nk_str_match_star(int c, const char *regexp, const char *text)
6610 {
6611  do {/* a '* matches zero or more instances */
6612  if (nk_str_match_here(regexp, text))
6613  return 1;
6614  } while (*text != '\0' && (*text++ == c || c == '.'));
6615  return 0;
6616 }
6617 NK_API int
6618 nk_strfilter(const char *text, const char *regexp)
6619 {
6620  /*
6621  c matches any literal character c
6622  . matches any single character
6623  ^ matches the beginning of the input string
6624  $ matches the end of the input string
6625  * matches zero or more occurrences of the previous character*/
6626  if (regexp[0] == '^')
6627  return nk_str_match_here(regexp+1, text);
6628  do { /* must look even if string is empty */
6629  if (nk_str_match_here(regexp, text))
6630  return 1;
6631  } while (*text++ != '\0');
6632  return 0;
6633 }
6634 NK_API int
6635 nk_strmatch_fuzzy_text(const char *str, int str_len,
6636  const char *pattern, int *out_score)
6637 {
6638  /* Returns true if each character in pattern is found sequentially within str
6639  * if found then out_score is also set. Score value has no intrinsic meaning.
6640  * Range varies with pattern. Can only compare scores with same search pattern. */
6641 
6642  /* bonus for adjacent matches */
6643  #define NK_ADJACENCY_BONUS 5
6644  /* bonus if match occurs after a separator */
6645  #define NK_SEPARATOR_BONUS 10
6646  /* bonus if match is uppercase and prev is lower */
6647  #define NK_CAMEL_BONUS 10
6648  /* penalty applied for every letter in str before the first match */
6649  #define NK_LEADING_LETTER_PENALTY (-3)
6650  /* maximum penalty for leading letters */
6651  #define NK_MAX_LEADING_LETTER_PENALTY (-9)
6652  /* penalty for every letter that doesn't matter */
6653  #define NK_UNMATCHED_LETTER_PENALTY (-1)
6654 
6655  /* loop variables */
6656  int score = 0;
6657  char const * pattern_iter = pattern;
6658  int str_iter = 0;
6659  int prev_matched = nk_false;
6660  int prev_lower = nk_false;
6661  /* true so if first letter match gets separator bonus*/
6662  int prev_separator = nk_true;
6663 
6664  /* use "best" matched letter if multiple string letters match the pattern */
6665  char const * best_letter = 0;
6666  int best_letter_score = 0;
6667 
6668  /* loop over strings */
6669  NK_ASSERT(str);
6670  NK_ASSERT(pattern);
6671  if (!str || !str_len || !pattern) return 0;
6672  while (str_iter < str_len)
6673  {
6674  const char pattern_letter = *pattern_iter;
6675  const char str_letter = str[str_iter];
6676 
6677  int next_match = *pattern_iter != '\0' &&
6678  nk_to_lower(pattern_letter) == nk_to_lower(str_letter);
6679  int rematch = best_letter && nk_to_upper(*best_letter) == nk_to_upper(str_letter);
6680 
6681  int advanced = next_match && best_letter;
6682  int pattern_repeat = best_letter && *pattern_iter != '\0';
6683  pattern_repeat = pattern_repeat &&
6684  nk_to_lower(*best_letter) == nk_to_lower(pattern_letter);
6685 
6686  if (advanced || pattern_repeat) {
6687  score += best_letter_score;
6688  best_letter = 0;
6689  best_letter_score = 0;
6690  }
6691 
6692  if (next_match || rematch)
6693  {
6694  int new_score = 0;
6695  /* Apply penalty for each letter before the first pattern match */
6696  if (pattern_iter == pattern) {
6697  int count = (int)(&str[str_iter] - str);
6698  int penalty = NK_LEADING_LETTER_PENALTY * count;
6699  if (penalty < NK_MAX_LEADING_LETTER_PENALTY)
6700  penalty = NK_MAX_LEADING_LETTER_PENALTY;
6701 
6702  score += penalty;
6703  }
6704 
6705  /* apply bonus for consecutive bonuses */
6706  if (prev_matched)
6707  new_score += NK_ADJACENCY_BONUS;
6708 
6709  /* apply bonus for matches after a separator */
6710  if (prev_separator)
6711  new_score += NK_SEPARATOR_BONUS;
6712 
6713  /* apply bonus across camel case boundaries */
6714  if (prev_lower && nk_is_upper(str_letter))
6715  new_score += NK_CAMEL_BONUS;
6716 
6717  /* update pattern iter IFF the next pattern letter was matched */
6718  if (next_match)
6719  ++pattern_iter;
6720 
6721  /* update best letter in str which may be for a "next" letter or a rematch */
6722  if (new_score >= best_letter_score) {
6723  /* apply penalty for now skipped letter */
6724  if (best_letter != 0)
6725  score += NK_UNMATCHED_LETTER_PENALTY;
6726 
6727  best_letter = &str[str_iter];
6728  best_letter_score = new_score;
6729  }
6730  prev_matched = nk_true;
6731  } else {
6732  score += NK_UNMATCHED_LETTER_PENALTY;
6733  prev_matched = nk_false;
6734  }
6735 
6736  /* separators should be more easily defined */
6737  prev_lower = nk_is_lower(str_letter) != 0;
6738  prev_separator = str_letter == '_' || str_letter == ' ';
6739 
6740  ++str_iter;
6741  }
6742 
6743  /* apply score for last match */
6744  if (best_letter)
6745  score += best_letter_score;
6746 
6747  /* did not match full pattern */
6748  if (*pattern_iter != '\0')
6749  return nk_false;
6750 
6751  if (out_score)
6752  *out_score = score;
6753  return nk_true;
6754 }
6755 NK_API int
6756 nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score)
6757 {
6758  return nk_strmatch_fuzzy_text(str, nk_strlen(str), pattern, out_score);
6759 }
6760 NK_LIB int
6761 nk_string_float_limit(char *string, int prec)
6762 {
6763  int dot = 0;
6764  char *c = string;
6765  while (*c) {
6766  if (*c == '.') {
6767  dot = 1;
6768  c++;
6769  continue;
6770  }
6771  if (dot == (prec+1)) {
6772  *c = 0;
6773  break;
6774  }
6775  if (dot > 0) dot++;
6776  c++;
6777  }
6778  return (int)(c - string);
6779 }
6780 NK_INTERN void
6781 nk_strrev_ascii(char *s)
6782 {
6783  int len = nk_strlen(s);
6784  int end = len / 2;
6785  int i = 0;
6786  char t;
6787  for (; i < end; ++i) {
6788  t = s[i];
6789  s[i] = s[len - 1 - i];
6790  s[len -1 - i] = t;
6791  }
6792 }
6793 NK_LIB char*
6794 nk_itoa(char *s, long n)
6795 {
6796  long i = 0;
6797  if (n == 0) {
6798  s[i++] = '0';
6799  s[i] = 0;
6800  return s;
6801  }
6802  if (n < 0) {
6803  s[i++] = '-';
6804  n = -n;
6805  }
6806  while (n > 0) {
6807  s[i++] = (char)('0' + (n % 10));
6808  n /= 10;
6809  }
6810  s[i] = 0;
6811  if (s[0] == '-')
6812  ++s;
6813 
6814  nk_strrev_ascii(s);
6815  return s;
6816 }
6817 NK_LIB char*
6818 nk_dtoa(char *s, double n)
6819 {
6820  int useExp = 0;
6821  int digit = 0, m = 0, m1 = 0;
6822  char *c = s;
6823  int neg = 0;
6824 
6825  NK_ASSERT(s);
6826  if (!s) return 0;
6827 
6828  if (n == 0.0) {
6829  s[0] = '0'; s[1] = '\0';
6830  return s;
6831  }
6832 
6833  neg = (n < 0);
6834  if (neg) n = -n;
6835 
6836  /* calculate magnitude */
6837  m = nk_log10(n);
6838  useExp = (m >= 14 || (neg && m >= 9) || m <= -9);
6839  if (neg) *(c++) = '-';
6840 
6841  /* set up for scientific notation */
6842  if (useExp) {
6843  if (m < 0)
6844  m -= 1;
6845  n = n / (double)nk_pow(10.0, m);
6846  m1 = m;
6847  m = 0;
6848  }
6849  if (m < 1.0) {
6850  m = 0;
6851  }
6852 
6853  /* convert the number */
6854  while (n > NK_FLOAT_PRECISION || m >= 0) {
6855  double weight = nk_pow(10.0, m);
6856  if (weight > 0) {
6857  double t = (double)n / weight;
6858  digit = nk_ifloord(t);
6859  n -= ((double)digit * weight);
6860  *(c++) = (char)('0' + (char)digit);
6861  }
6862  if (m == 0 && n > 0)
6863  *(c++) = '.';
6864  m--;
6865  }
6866 
6867  if (useExp) {
6868  /* convert the exponent */
6869  int i, j;
6870  *(c++) = 'e';
6871  if (m1 > 0) {
6872  *(c++) = '+';
6873  } else {
6874  *(c++) = '-';
6875  m1 = -m1;
6876  }
6877  m = 0;
6878  while (m1 > 0) {
6879  *(c++) = (char)('0' + (char)(m1 % 10));
6880  m1 /= 10;
6881  m++;
6882  }
6883  c -= m;
6884  for (i = 0, j = m-1; i<j; i++, j--) {
6885  /* swap without temporary */
6886  c[i] ^= c[j];
6887  c[j] ^= c[i];
6888  c[i] ^= c[j];
6889  }
6890  c += m;
6891  }
6892  *(c) = '\0';
6893  return s;
6894 }
6895 #ifdef NK_INCLUDE_STANDARD_VARARGS
6896 #ifndef NK_INCLUDE_STANDARD_IO
6897 NK_INTERN int
6898 nk_vsnprintf(char *buf, int buf_size, const char *fmt, va_list args)
6899 {
6900  enum nk_arg_type {
6901  NK_ARG_TYPE_CHAR,
6902  NK_ARG_TYPE_SHORT,
6903  NK_ARG_TYPE_DEFAULT,
6904  NK_ARG_TYPE_LONG
6905  };
6906  enum nk_arg_flags {
6907  NK_ARG_FLAG_LEFT = 0x01,
6908  NK_ARG_FLAG_PLUS = 0x02,
6909  NK_ARG_FLAG_SPACE = 0x04,
6910  NK_ARG_FLAG_NUM = 0x10,
6911  NK_ARG_FLAG_ZERO = 0x20
6912  };
6913 
6914  char number_buffer[NK_MAX_NUMBER_BUFFER];
6915  enum nk_arg_type arg_type = NK_ARG_TYPE_DEFAULT;
6916  int precision = NK_DEFAULT;
6917  int width = NK_DEFAULT;
6918  nk_flags flag = 0;
6919 
6920  int len = 0;
6921  int result = -1;
6922  const char *iter = fmt;
6923 
6924  NK_ASSERT(buf);
6925  NK_ASSERT(buf_size);
6926  if (!buf || !buf_size || !fmt) return 0;
6927  for (iter = fmt; *iter && len < buf_size; iter++) {
6928  /* copy all non-format characters */
6929  while (*iter && (*iter != '%') && (len < buf_size))
6930  buf[len++] = *iter++;
6931  if (!(*iter) || len >= buf_size) break;
6932  iter++;
6933 
6934  /* flag arguments */
6935  while (*iter) {
6936  if (*iter == '-') flag |= NK_ARG_FLAG_LEFT;
6937  else if (*iter == '+') flag |= NK_ARG_FLAG_PLUS;
6938  else if (*iter == ' ') flag |= NK_ARG_FLAG_SPACE;
6939  else if (*iter == '#') flag |= NK_ARG_FLAG_NUM;
6940  else if (*iter == '0') flag |= NK_ARG_FLAG_ZERO;
6941  else break;
6942  iter++;
6943  }
6944 
6945  /* width argument */
6946  width = NK_DEFAULT;
6947  if (*iter >= '1' && *iter <= '9') {
6948  const char *end;
6949  width = nk_strtoi(iter, &end);
6950  if (end == iter)
6951  width = -1;
6952  else iter = end;
6953  } else if (*iter == '*') {
6954  width = va_arg(args, int);
6955  iter++;
6956  }
6957 
6958  /* precision argument */
6959  precision = NK_DEFAULT;
6960  if (*iter == '.') {
6961  iter++;
6962  if (*iter == '*') {
6963  precision = va_arg(args, int);
6964  iter++;
6965  } else {
6966  const char *end;
6967  precision = nk_strtoi(iter, &end);
6968  if (end == iter)
6969  precision = -1;
6970  else iter = end;
6971  }
6972  }
6973 
6974  /* length modifier */
6975  if (*iter == 'h') {
6976  if (*(iter+1) == 'h') {
6977  arg_type = NK_ARG_TYPE_CHAR;
6978  iter++;
6979  } else arg_type = NK_ARG_TYPE_SHORT;
6980  iter++;
6981  } else if (*iter == 'l') {
6982  arg_type = NK_ARG_TYPE_LONG;
6983  iter++;
6984  } else arg_type = NK_ARG_TYPE_DEFAULT;
6985 
6986  /* specifier */
6987  if (*iter == '%') {
6988  NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
6989  NK_ASSERT(precision == NK_DEFAULT);
6990  NK_ASSERT(width == NK_DEFAULT);
6991  if (len < buf_size)
6992  buf[len++] = '%';
6993  } else if (*iter == 's') {
6994  /* string */
6995  const char *str = va_arg(args, const char*);
6996  NK_ASSERT(str != buf && "buffer and argument are not allowed to overlap!");
6997  NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
6998  NK_ASSERT(precision == NK_DEFAULT);
6999  NK_ASSERT(width == NK_DEFAULT);
7000  if (str == buf) return -1;
7001  while (str && *str && len < buf_size)
7002  buf[len++] = *str++;
7003  } else if (*iter == 'n') {
7004  /* current length callback */
7005  signed int *n = va_arg(args, int*);
7006  NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
7007  NK_ASSERT(precision == NK_DEFAULT);
7008  NK_ASSERT(width == NK_DEFAULT);
7009  if (n) *n = len;
7010  } else if (*iter == 'c' || *iter == 'i' || *iter == 'd') {
7011  /* signed integer */
7012  long value = 0;
7013  const char *num_iter;
7014  int num_len, num_print, padding;
7015  int cur_precision = NK_MAX(precision, 1);
7016  int cur_width = NK_MAX(width, 0);
7017 
7018  /* retrieve correct value type */
7019  if (arg_type == NK_ARG_TYPE_CHAR)
7020  value = (signed char)va_arg(args, int);
7021  else if (arg_type == NK_ARG_TYPE_SHORT)
7022  value = (signed short)va_arg(args, int);
7023  else if (arg_type == NK_ARG_TYPE_LONG)
7024  value = va_arg(args, signed long);
7025  else if (*iter == 'c')
7026  value = (unsigned char)va_arg(args, int);
7027  else value = va_arg(args, signed int);
7028 
7029  /* convert number to string */
7030  nk_itoa(number_buffer, value);
7031  num_len = nk_strlen(number_buffer);
7032  padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0);
7033  if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE))
7034  padding = NK_MAX(padding-1, 0);
7035 
7036  /* fill left padding up to a total of `width` characters */
7037  if (!(flag & NK_ARG_FLAG_LEFT)) {
7038  while (padding-- > 0 && (len < buf_size)) {
7039  if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT))
7040  buf[len++] = '0';
7041  else buf[len++] = ' ';
7042  }
7043  }
7044 
7045  /* copy string value representation into buffer */
7046  if ((flag & NK_ARG_FLAG_PLUS) && value >= 0 && len < buf_size)
7047  buf[len++] = '+';
7048  else if ((flag & NK_ARG_FLAG_SPACE) && value >= 0 && len < buf_size)
7049  buf[len++] = ' ';
7050 
7051  /* fill up to precision number of digits with '0' */
7052  num_print = NK_MAX(cur_precision, num_len);
7053  while (precision && (num_print > num_len) && (len < buf_size)) {
7054  buf[len++] = '0';
7055  num_print--;
7056  }
7057 
7058  /* copy string value representation into buffer */
7059  num_iter = number_buffer;
7060  while (precision && *num_iter && len < buf_size)
7061  buf[len++] = *num_iter++;
7062 
7063  /* fill right padding up to width characters */
7064  if (flag & NK_ARG_FLAG_LEFT) {
7065  while ((padding-- > 0) && (len < buf_size))
7066  buf[len++] = ' ';
7067  }
7068  } else if (*iter == 'o' || *iter == 'x' || *iter == 'X' || *iter == 'u') {
7069  /* unsigned integer */
7070  unsigned long value = 0;
7071  int num_len = 0, num_print, padding = 0;
7072  int cur_precision = NK_MAX(precision, 1);
7073  int cur_width = NK_MAX(width, 0);
7074  unsigned int base = (*iter == 'o') ? 8: (*iter == 'u')? 10: 16;
7075 
7076  /* print oct/hex/dec value */
7077  const char *upper_output_format = "0123456789ABCDEF";
7078  const char *lower_output_format = "0123456789abcdef";
7079  const char *output_format = (*iter == 'x') ?
7080  lower_output_format: upper_output_format;
7081 
7082  /* retrieve correct value type */
7083  if (arg_type == NK_ARG_TYPE_CHAR)
7084  value = (unsigned char)va_arg(args, int);
7085  else if (arg_type == NK_ARG_TYPE_SHORT)
7086  value = (unsigned short)va_arg(args, int);
7087  else if (arg_type == NK_ARG_TYPE_LONG)
7088  value = va_arg(args, unsigned long);
7089  else value = va_arg(args, unsigned int);
7090 
7091  do {
7092  /* convert decimal number into hex/oct number */
7093  int digit = output_format[value % base];
7094  if (num_len < NK_MAX_NUMBER_BUFFER)
7095  number_buffer[num_len++] = (char)digit;
7096  value /= base;
7097  } while (value > 0);
7098 
7099  num_print = NK_MAX(cur_precision, num_len);
7100  padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0);
7101  if (flag & NK_ARG_FLAG_NUM)
7102  padding = NK_MAX(padding-1, 0);
7103 
7104  /* fill left padding up to a total of `width` characters */
7105  if (!(flag & NK_ARG_FLAG_LEFT)) {
7106  while ((padding-- > 0) && (len < buf_size)) {
7107  if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT))
7108  buf[len++] = '0';
7109  else buf[len++] = ' ';
7110  }
7111  }
7112 
7113  /* fill up to precision number of digits */
7114  if (num_print && (flag & NK_ARG_FLAG_NUM)) {
7115  if ((*iter == 'o') && (len < buf_size)) {
7116  buf[len++] = '0';
7117  } else if ((*iter == 'x') && ((len+1) < buf_size)) {
7118  buf[len++] = '0';
7119  buf[len++] = 'x';
7120  } else if ((*iter == 'X') && ((len+1) < buf_size)) {
7121  buf[len++] = '0';
7122  buf[len++] = 'X';
7123  }
7124  }
7125  while (precision && (num_print > num_len) && (len < buf_size)) {
7126  buf[len++] = '0';
7127  num_print--;
7128  }
7129 
7130  /* reverse number direction */
7131  while (num_len > 0) {
7132  if (precision && (len < buf_size))
7133  buf[len++] = number_buffer[num_len-1];
7134  num_len--;
7135  }
7136 
7137  /* fill right padding up to width characters */
7138  if (flag & NK_ARG_FLAG_LEFT) {
7139  while ((padding-- > 0) && (len < buf_size))
7140  buf[len++] = ' ';
7141  }
7142  } else if (*iter == 'f') {
7143  /* floating point */
7144  const char *num_iter;
7145  int cur_precision = (precision < 0) ? 6: precision;
7146  int prefix, cur_width = NK_MAX(width, 0);
7147  double value = va_arg(args, double);
7148  int num_len = 0, frac_len = 0, dot = 0;
7149  int padding = 0;
7150 
7151  NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
7152  NK_DTOA(number_buffer, value);
7153  num_len = nk_strlen(number_buffer);
7154 
7155  /* calculate padding */
7156  num_iter = number_buffer;
7157  while (*num_iter && *num_iter != '.')
7158  num_iter++;
7159 
7160  prefix = (*num_iter == '.')?(int)(num_iter - number_buffer)+1:0;
7161  padding = NK_MAX(cur_width - (prefix + NK_MIN(cur_precision, num_len - prefix)) , 0);
7162  if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE))
7163  padding = NK_MAX(padding-1, 0);
7164 
7165  /* fill left padding up to a total of `width` characters */
7166  if (!(flag & NK_ARG_FLAG_LEFT)) {
7167  while (padding-- > 0 && (len < buf_size)) {
7168  if (flag & NK_ARG_FLAG_ZERO)
7169  buf[len++] = '0';
7170  else buf[len++] = ' ';
7171  }
7172  }
7173 
7174  /* copy string value representation into buffer */
7175  num_iter = number_buffer;
7176  if ((flag & NK_ARG_FLAG_PLUS) && (value >= 0) && (len < buf_size))
7177  buf[len++] = '+';
7178  else if ((flag & NK_ARG_FLAG_SPACE) && (value >= 0) && (len < buf_size))
7179  buf[len++] = ' ';
7180  while (*num_iter) {
7181  if (dot) frac_len++;
7182  if (len < buf_size)
7183  buf[len++] = *num_iter;
7184  if (*num_iter == '.') dot = 1;
7185  if (frac_len >= cur_precision) break;
7186  num_iter++;
7187  }
7188 
7189  /* fill number up to precision */
7190  while (frac_len < cur_precision) {
7191  if (!dot && len < buf_size) {
7192  buf[len++] = '.';
7193  dot = 1;
7194  }
7195  if (len < buf_size)
7196  buf[len++] = '0';
7197  frac_len++;
7198  }
7199 
7200  /* fill right padding up to width characters */
7201  if (flag & NK_ARG_FLAG_LEFT) {
7202  while ((padding-- > 0) && (len < buf_size))
7203  buf[len++] = ' ';
7204  }
7205  } else {
7206  /* Specifier not supported: g,G,e,E,p,z */
7207  NK_ASSERT(0 && "specifier is not supported!");
7208  return result;
7209  }
7210  }
7211  buf[(len >= buf_size)?(buf_size-1):len] = 0;
7212  result = (len >= buf_size)?-1:len;
7213  return result;
7214 }
7215 #endif
7216 NK_LIB int
7217 nk_strfmt(char *buf, int buf_size, const char *fmt, va_list args)
7218 {
7219  int result = -1;
7220  NK_ASSERT(buf);
7221  NK_ASSERT(buf_size);
7222  if (!buf || !buf_size || !fmt) return 0;
7223 #ifdef NK_INCLUDE_STANDARD_IO
7224  result = NK_VSNPRINTF(buf, (nk_size)buf_size, fmt, args);
7225  result = (result >= buf_size) ? -1: result;
7226  buf[buf_size-1] = 0;
7227 #else
7228  result = nk_vsnprintf(buf, buf_size, fmt, args);
7229 #endif
7230  return result;
7231 }
7232 #endif
7234 nk_murmur_hash(const void * key, int len, nk_hash seed)
7235 {
7236  /* 32-Bit MurmurHash3: https://code.google.com/p/smhasher/wiki/MurmurHash3*/
7237  #define NK_ROTL(x,r) ((x) << (r) | ((x) >> (32 - r)))
7238 
7239  nk_uint h1 = seed;
7240  nk_uint k1;
7241  const nk_byte *data = (const nk_byte*)key;
7242  const nk_byte *keyptr = data;
7243  nk_byte *k1ptr;
7244  const int bsize = sizeof(k1);
7245  const int nblocks = len/4;
7246 
7247  const nk_uint c1 = 0xcc9e2d51;
7248  const nk_uint c2 = 0x1b873593;
7249  const nk_byte *tail;
7250  int i;
7251 
7252  /* body */
7253  if (!key) return 0;
7254  for (i = 0; i < nblocks; ++i, keyptr += bsize) {
7255  k1ptr = (nk_byte*)&k1;
7256  k1ptr[0] = keyptr[0];
7257  k1ptr[1] = keyptr[1];
7258  k1ptr[2] = keyptr[2];
7259  k1ptr[3] = keyptr[3];
7260 
7261  k1 *= c1;
7262  k1 = NK_ROTL(k1,15);
7263  k1 *= c2;
7264 
7265  h1 ^= k1;
7266  h1 = NK_ROTL(h1,13);
7267  h1 = h1*5+0xe6546b64;
7268  }
7269 
7270  /* tail */
7271  tail = (const nk_byte*)(data + nblocks*4);
7272  k1 = 0;
7273  switch (len & 3) {
7274  case 3: k1 ^= (nk_uint)(tail[2] << 16); /* fallthrough */
7275  case 2: k1 ^= (nk_uint)(tail[1] << 8u); /* fallthrough */
7276  case 1: k1 ^= tail[0];
7277  k1 *= c1;
7278  k1 = NK_ROTL(k1,15);
7279  k1 *= c2;
7280  h1 ^= k1;
7281  break;
7282  default: break;
7283  }
7284 
7285  /* finalization */
7286  h1 ^= (nk_uint)len;
7287  /* fmix32 */
7288  h1 ^= h1 >> 16;
7289  h1 *= 0x85ebca6b;
7290  h1 ^= h1 >> 13;
7291  h1 *= 0xc2b2ae35;
7292  h1 ^= h1 >> 16;
7293 
7294  #undef NK_ROTL
7295  return h1;
7296 }
7297 #ifdef NK_INCLUDE_STANDARD_IO
7298 NK_LIB char*
7299 nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc)
7300 {
7301  char *buf;
7302  FILE *fd;
7303  long ret;
7304 
7305  NK_ASSERT(path);
7306  NK_ASSERT(siz);
7307  NK_ASSERT(alloc);
7308  if (!path || !siz || !alloc)
7309  return 0;
7310 
7311  fd = fopen(path, "rb");
7312  if (!fd) return 0;
7313  fseek(fd, 0, SEEK_END);
7314  ret = ftell(fd);
7315  if (ret < 0) {
7316  fclose(fd);
7317  return 0;
7318  }
7319  *siz = (nk_size)ret;
7320  fseek(fd, 0, SEEK_SET);
7321  buf = (char*)alloc->alloc(alloc->userdata,0, *siz);
7322  NK_ASSERT(buf);
7323  if (!buf) {
7324  fclose(fd);
7325  return 0;
7326  }
7327  *siz = (nk_size)fread(buf, 1,*siz, fd);
7328  fclose(fd);
7329  return buf;
7330 }
7331 #endif
7332 NK_LIB int
7333 nk_text_clamp(const struct nk_user_font *font, const char *text,
7334  int text_len, float space, int *glyphs, float *text_width,
7335  nk_rune *sep_list, int sep_count)
7336 {
7337  int i = 0;
7338  int glyph_len = 0;
7339  float last_width = 0;
7340  nk_rune unicode = 0;
7341  float width = 0;
7342  int len = 0;
7343  int g = 0;
7344  float s;
7345 
7346  int sep_len = 0;
7347  int sep_g = 0;
7348  float sep_width = 0;
7349  sep_count = NK_MAX(sep_count,0);
7350 
7351  glyph_len = nk_utf_decode(text, &unicode, text_len);
7352  while (glyph_len && (width < space) && (len < text_len)) {
7353  len += glyph_len;
7354  s = font->width(font->userdata, font->height, text, len);
7355  for (i = 0; i < sep_count; ++i) {
7356  if (unicode != sep_list[i]) continue;
7357  sep_width = last_width = width;
7358  sep_g = g+1;
7359  sep_len = len;
7360  break;
7361  }
7362  if (i == sep_count){
7363  last_width = sep_width = width;
7364  sep_g = g+1;
7365  }
7366  width = s;
7367  glyph_len = nk_utf_decode(&text[len], &unicode, text_len - len);
7368  g++;
7369  }
7370  if (len >= text_len) {
7371  *glyphs = g;
7372  *text_width = last_width;
7373  return len;
7374  } else {
7375  *glyphs = sep_g;
7376  *text_width = sep_width;
7377  return (!sep_len) ? len: sep_len;
7378  }
7379 }
7380 NK_LIB struct nk_vec2
7381 nk_text_calculate_text_bounds(const struct nk_user_font *font,
7382  const char *begin, int byte_len, float row_height, const char **remaining,
7383  struct nk_vec2 *out_offset, int *glyphs, int op)
7384 {
7385  float line_height = row_height;
7386  struct nk_vec2 text_size = nk_vec2(0,0);
7387  float line_width = 0.0f;
7388 
7389  float glyph_width;
7390  int glyph_len = 0;
7391  nk_rune unicode = 0;
7392  int text_len = 0;
7393  if (!begin || byte_len <= 0 || !font)
7394  return nk_vec2(0,row_height);
7395 
7396  glyph_len = nk_utf_decode(begin, &unicode, byte_len);
7397  if (!glyph_len) return text_size;
7398  glyph_width = font->width(font->userdata, font->height, begin, glyph_len);
7399 
7400  *glyphs = 0;
7401  while ((text_len < byte_len) && glyph_len) {
7402  if (unicode == '\n') {
7403  text_size.x = NK_MAX(text_size.x, line_width);
7404  text_size.y += line_height;
7405  line_width = 0;
7406  *glyphs+=1;
7407  if (op == NK_STOP_ON_NEW_LINE)
7408  break;
7409 
7410  text_len++;
7411  glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
7412  continue;
7413  }
7414 
7415  if (unicode == '\r') {
7416  text_len++;
7417  *glyphs+=1;
7418  glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
7419  continue;
7420  }
7421 
7422  *glyphs = *glyphs + 1;
7423  text_len += glyph_len;
7424  line_width += (float)glyph_width;
7425  glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
7426  glyph_width = font->width(font->userdata, font->height, begin+text_len, glyph_len);
7427  continue;
7428  }
7429 
7430  if (text_size.x < line_width)
7431  text_size.x = line_width;
7432  if (out_offset)
7433  *out_offset = nk_vec2(line_width, text_size.y + line_height);
7434  if (line_width > 0 || text_size.y == 0.0f)
7435  text_size.y += line_height;
7436  if (remaining)
7437  *remaining = begin+text_len;
7438  return text_size;
7439 }
7440 
7441 
7442 
7443 
7444 
7445 /* ==============================================================
7446  *
7447  * COLOR
7448  *
7449  * ===============================================================*/
7450 NK_INTERN int
7451 nk_parse_hex(const char *p, int length)
7452 {
7453  int i = 0;
7454  int len = 0;
7455  while (len < length) {
7456  i <<= 4;
7457  if (p[len] >= 'a' && p[len] <= 'f')
7458  i += ((p[len] - 'a') + 10);
7459  else if (p[len] >= 'A' && p[len] <= 'F')
7460  i += ((p[len] - 'A') + 10);
7461  else i += (p[len] - '0');
7462  len++;
7463  }
7464  return i;
7465 }
7466 NK_API struct nk_color
7467 nk_rgba(int r, int g, int b, int a)
7468 {
7469  struct nk_color ret;
7470  ret.r = (nk_byte)NK_CLAMP(0, r, 255);
7471  ret.g = (nk_byte)NK_CLAMP(0, g, 255);
7472  ret.b = (nk_byte)NK_CLAMP(0, b, 255);
7473  ret.a = (nk_byte)NK_CLAMP(0, a, 255);
7474  return ret;
7475 }
7476 NK_API struct nk_color
7477 nk_rgb_hex(const char *rgb)
7478 {
7479  struct nk_color col;
7480  const char *c = rgb;
7481  if (*c == '#') c++;
7482  col.r = (nk_byte)nk_parse_hex(c, 2);
7483  col.g = (nk_byte)nk_parse_hex(c+2, 2);
7484  col.b = (nk_byte)nk_parse_hex(c+4, 2);
7485  col.a = 255;
7486  return col;
7487 }
7488 NK_API struct nk_color
7489 nk_rgba_hex(const char *rgb)
7490 {
7491  struct nk_color col;
7492  const char *c = rgb;
7493  if (*c == '#') c++;
7494  col.r = (nk_byte)nk_parse_hex(c, 2);
7495  col.g = (nk_byte)nk_parse_hex(c+2, 2);
7496  col.b = (nk_byte)nk_parse_hex(c+4, 2);
7497  col.a = (nk_byte)nk_parse_hex(c+6, 2);
7498  return col;
7499 }
7500 NK_API void
7501 nk_color_hex_rgba(char *output, struct nk_color col)
7502 {
7503  #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i))
7504  output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4);
7505  output[1] = (char)NK_TO_HEX((col.r & 0x0F));
7506  output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4);
7507  output[3] = (char)NK_TO_HEX((col.g & 0x0F));
7508  output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4);
7509  output[5] = (char)NK_TO_HEX((col.b & 0x0F));
7510  output[6] = (char)NK_TO_HEX((col.a & 0xF0) >> 4);
7511  output[7] = (char)NK_TO_HEX((col.a & 0x0F));
7512  output[8] = '\0';
7513  #undef NK_TO_HEX
7514 }
7515 NK_API void
7516 nk_color_hex_rgb(char *output, struct nk_color col)
7517 {
7518  #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i))
7519  output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4);
7520  output[1] = (char)NK_TO_HEX((col.r & 0x0F));
7521  output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4);
7522  output[3] = (char)NK_TO_HEX((col.g & 0x0F));
7523  output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4);
7524  output[5] = (char)NK_TO_HEX((col.b & 0x0F));
7525  output[6] = '\0';
7526  #undef NK_TO_HEX
7527 }
7528 NK_API struct nk_color
7529 nk_rgba_iv(const int *c)
7530 {
7531  return nk_rgba(c[0], c[1], c[2], c[3]);
7532 }
7533 NK_API struct nk_color
7534 nk_rgba_bv(const nk_byte *c)
7535 {
7536  return nk_rgba(c[0], c[1], c[2], c[3]);
7537 }
7538 NK_API struct nk_color
7539 nk_rgb(int r, int g, int b)
7540 {
7541  struct nk_color ret;
7542  ret.r = (nk_byte)NK_CLAMP(0, r, 255);
7543  ret.g = (nk_byte)NK_CLAMP(0, g, 255);
7544  ret.b = (nk_byte)NK_CLAMP(0, b, 255);
7545  ret.a = (nk_byte)255;
7546  return ret;
7547 }
7548 NK_API struct nk_color
7549 nk_rgb_iv(const int *c)
7550 {
7551  return nk_rgb(c[0], c[1], c[2]);
7552 }
7553 NK_API struct nk_color
7554 nk_rgb_bv(const nk_byte* c)
7555 {
7556  return nk_rgb(c[0], c[1], c[2]);
7557 }
7558 NK_API struct nk_color
7559 nk_rgba_u32(nk_uint in)
7560 {
7561  struct nk_color ret;
7562  ret.r = (in & 0xFF);
7563  ret.g = ((in >> 8) & 0xFF);
7564  ret.b = ((in >> 16) & 0xFF);
7565  ret.a = (nk_byte)((in >> 24) & 0xFF);
7566  return ret;
7567 }
7568 NK_API struct nk_color
7569 nk_rgba_f(float r, float g, float b, float a)
7570 {
7571  struct nk_color ret;
7572  ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f);
7573  ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f);
7574  ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f);
7575  ret.a = (nk_byte)(NK_SATURATE(a) * 255.0f);
7576  return ret;
7577 }
7578 NK_API struct nk_color
7579 nk_rgba_fv(const float *c)
7580 {
7581  return nk_rgba_f(c[0], c[1], c[2], c[3]);
7582 }
7583 NK_API struct nk_color
7584 nk_rgba_cf(struct nk_colorf c)
7585 {
7586  return nk_rgba_f(c.r, c.g, c.b, c.a);
7587 }
7588 NK_API struct nk_color
7589 nk_rgb_f(float r, float g, float b)
7590 {
7591  struct nk_color ret;
7592  ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f);
7593  ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f);
7594  ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f);
7595  ret.a = 255;
7596  return ret;
7597 }
7598 NK_API struct nk_color
7599 nk_rgb_fv(const float *c)
7600 {
7601  return nk_rgb_f(c[0], c[1], c[2]);
7602 }
7603 NK_API struct nk_color
7604 nk_rgb_cf(struct nk_colorf c)
7605 {
7606  return nk_rgb_f(c.r, c.g, c.b);
7607 }
7608 NK_API struct nk_color
7609 nk_hsv(int h, int s, int v)
7610 {
7611  return nk_hsva(h, s, v, 255);
7612 }
7613 NK_API struct nk_color
7614 nk_hsv_iv(const int *c)
7615 {
7616  return nk_hsv(c[0], c[1], c[2]);
7617 }
7618 NK_API struct nk_color
7619 nk_hsv_bv(const nk_byte *c)
7620 {
7621  return nk_hsv(c[0], c[1], c[2]);
7622 }
7623 NK_API struct nk_color
7624 nk_hsv_f(float h, float s, float v)
7625 {
7626  return nk_hsva_f(h, s, v, 1.0f);
7627 }
7628 NK_API struct nk_color
7629 nk_hsv_fv(const float *c)
7630 {
7631  return nk_hsv_f(c[0], c[1], c[2]);
7632 }
7633 NK_API struct nk_color
7634 nk_hsva(int h, int s, int v, int a)
7635 {
7636  float hf = ((float)NK_CLAMP(0, h, 255)) / 255.0f;
7637  float sf = ((float)NK_CLAMP(0, s, 255)) / 255.0f;
7638  float vf = ((float)NK_CLAMP(0, v, 255)) / 255.0f;
7639  float af = ((float)NK_CLAMP(0, a, 255)) / 255.0f;
7640  return nk_hsva_f(hf, sf, vf, af);
7641 }
7642 NK_API struct nk_color
7643 nk_hsva_iv(const int *c)
7644 {
7645  return nk_hsva(c[0], c[1], c[2], c[3]);
7646 }
7647 NK_API struct nk_color
7648 nk_hsva_bv(const nk_byte *c)
7649 {
7650  return nk_hsva(c[0], c[1], c[2], c[3]);
7651 }
7652 NK_API struct nk_colorf
7653 nk_hsva_colorf(float h, float s, float v, float a)
7654 {
7655  int i;
7656  float p, q, t, f;
7657  struct nk_colorf out = {0,0,0,0};
7658  if (s <= 0.0f) {
7659  out.r = v; out.g = v; out.b = v; out.a = a;
7660  return out;
7661  }
7662  h = h / (60.0f/360.0f);
7663  i = (int)h;
7664  f = h - (float)i;
7665  p = v * (1.0f - s);
7666  q = v * (1.0f - (s * f));
7667  t = v * (1.0f - s * (1.0f - f));
7668 
7669  switch (i) {
7670  case 0: default: out.r = v; out.g = t; out.b = p; break;
7671  case 1: out.r = q; out.g = v; out.b = p; break;
7672  case 2: out.r = p; out.g = v; out.b = t; break;
7673  case 3: out.r = p; out.g = q; out.b = v; break;
7674  case 4: out.r = t; out.g = p; out.b = v; break;
7675  case 5: out.r = v; out.g = p; out.b = q; break;}
7676  out.a = a;
7677  return out;
7678 }
7679 NK_API struct nk_colorf
7680 nk_hsva_colorfv(float *c)
7681 {
7682  return nk_hsva_colorf(c[0], c[1], c[2], c[3]);
7683 }
7684 NK_API struct nk_color
7685 nk_hsva_f(float h, float s, float v, float a)
7686 {
7687  struct nk_colorf c = nk_hsva_colorf(h, s, v, a);
7688  return nk_rgba_f(c.r, c.g, c.b, c.a);
7689 }
7690 NK_API struct nk_color
7691 nk_hsva_fv(const float *c)
7692 {
7693  return nk_hsva_f(c[0], c[1], c[2], c[3]);
7694 }
7696 nk_color_u32(struct nk_color in)
7697 {
7698  nk_uint out = (nk_uint)in.r;
7699  out |= ((nk_uint)in.g << 8);
7700  out |= ((nk_uint)in.b << 16);
7701  out |= ((nk_uint)in.a << 24);
7702  return out;
7703 }
7704 NK_API void
7705 nk_color_f(float *r, float *g, float *b, float *a, struct nk_color in)
7706 {
7707  NK_STORAGE const float s = 1.0f/255.0f;
7708  *r = (float)in.r * s;
7709  *g = (float)in.g * s;
7710  *b = (float)in.b * s;
7711  *a = (float)in.a * s;
7712 }
7713 NK_API void
7714 nk_color_fv(float *c, struct nk_color in)
7715 {
7716  nk_color_f(&c[0], &c[1], &c[2], &c[3], in);
7717 }
7718 NK_API struct nk_colorf
7719 nk_color_cf(struct nk_color in)
7720 {
7721  struct nk_colorf o;
7722  nk_color_f(&o.r, &o.g, &o.b, &o.a, in);
7723  return o;
7724 }
7725 NK_API void
7726 nk_color_d(double *r, double *g, double *b, double *a, struct nk_color in)
7727 {
7728  NK_STORAGE const double s = 1.0/255.0;
7729  *r = (double)in.r * s;
7730  *g = (double)in.g * s;
7731  *b = (double)in.b * s;
7732  *a = (double)in.a * s;
7733 }
7734 NK_API void
7735 nk_color_dv(double *c, struct nk_color in)
7736 {
7737  nk_color_d(&c[0], &c[1], &c[2], &c[3], in);
7738 }
7739 NK_API void
7740 nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color in)
7741 {
7742  float a;
7743  nk_color_hsva_f(out_h, out_s, out_v, &a, in);
7744 }
7745 NK_API void
7746 nk_color_hsv_fv(float *out, struct nk_color in)
7747 {
7748  float a;
7749  nk_color_hsva_f(&out[0], &out[1], &out[2], &a, in);
7750 }
7751 NK_API void
7752 nk_colorf_hsva_f(float *out_h, float *out_s,
7753  float *out_v, float *out_a, struct nk_colorf in)
7754 {
7755  float chroma;
7756  float K = 0.0f;
7757  if (in.g < in.b) {
7758  const float t = in.g; in.g = in.b; in.b = t;
7759  K = -1.f;
7760  }
7761  if (in.r < in.g) {
7762  const float t = in.r; in.r = in.g; in.g = t;
7763  K = -2.f/6.0f - K;
7764  }
7765  chroma = in.r - ((in.g < in.b) ? in.g: in.b);
7766  *out_h = NK_ABS(K + (in.g - in.b)/(6.0f * chroma + 1e-20f));
7767  *out_s = chroma / (in.r + 1e-20f);
7768  *out_v = in.r;
7769  *out_a = in.a;
7770 
7771 }
7772 NK_API void
7773 nk_colorf_hsva_fv(float *hsva, struct nk_colorf in)
7774 {
7775  nk_colorf_hsva_f(&hsva[0], &hsva[1], &hsva[2], &hsva[3], in);
7776 }
7777 NK_API void
7778 nk_color_hsva_f(float *out_h, float *out_s,
7779  float *out_v, float *out_a, struct nk_color in)
7780 {
7781  struct nk_colorf col;
7782  nk_color_f(&col.r,&col.g,&col.b,&col.a, in);
7783  nk_colorf_hsva_f(out_h, out_s, out_v, out_a, col);
7784 }
7785 NK_API void
7786 nk_color_hsva_fv(float *out, struct nk_color in)
7787 {
7788  nk_color_hsva_f(&out[0], &out[1], &out[2], &out[3], in);
7789 }
7790 NK_API void
7791 nk_color_hsva_i(int *out_h, int *out_s, int *out_v,
7792  int *out_a, struct nk_color in)
7793 {
7794  float h,s,v,a;
7795  nk_color_hsva_f(&h, &s, &v, &a, in);
7796  *out_h = (nk_byte)(h * 255.0f);
7797  *out_s = (nk_byte)(s * 255.0f);
7798  *out_v = (nk_byte)(v * 255.0f);
7799  *out_a = (nk_byte)(a * 255.0f);
7800 }
7801 NK_API void
7802 nk_color_hsva_iv(int *out, struct nk_color in)
7803 {
7804  nk_color_hsva_i(&out[0], &out[1], &out[2], &out[3], in);
7805 }
7806 NK_API void
7807 nk_color_hsva_bv(nk_byte *out, struct nk_color in)
7808 {
7809  int tmp[4];
7810  nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
7811  out[0] = (nk_byte)tmp[0];
7812  out[1] = (nk_byte)tmp[1];
7813  out[2] = (nk_byte)tmp[2];
7814  out[3] = (nk_byte)tmp[3];
7815 }
7816 NK_API void
7817 nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a, struct nk_color in)
7818 {
7819  int tmp[4];
7820  nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
7821  *h = (nk_byte)tmp[0];
7822  *s = (nk_byte)tmp[1];
7823  *v = (nk_byte)tmp[2];
7824  *a = (nk_byte)tmp[3];
7825 }
7826 NK_API void
7827 nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color in)
7828 {
7829  int a;
7830  nk_color_hsva_i(out_h, out_s, out_v, &a, in);
7831 }
7832 NK_API void
7833 nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color in)
7834 {
7835  int tmp[4];
7836  nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
7837  *out_h = (nk_byte)tmp[0];
7838  *out_s = (nk_byte)tmp[1];
7839  *out_v = (nk_byte)tmp[2];
7840 }
7841 NK_API void
7842 nk_color_hsv_iv(int *out, struct nk_color in)
7843 {
7844  nk_color_hsv_i(&out[0], &out[1], &out[2], in);
7845 }
7846 NK_API void
7847 nk_color_hsv_bv(nk_byte *out, struct nk_color in)
7848 {
7849  int tmp[4];
7850  nk_color_hsv_i(&tmp[0], &tmp[1], &tmp[2], in);
7851  out[0] = (nk_byte)tmp[0];
7852  out[1] = (nk_byte)tmp[1];
7853  out[2] = (nk_byte)tmp[2];
7854 }
7855 
7856 
7857 
7858 
7859 
7860 /* ===============================================================
7861  *
7862  * UTF-8
7863  *
7864  * ===============================================================*/
7865 NK_GLOBAL const nk_byte nk_utfbyte[NK_UTF_SIZE+1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
7866 NK_GLOBAL const nk_byte nk_utfmask[NK_UTF_SIZE+1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
7867 NK_GLOBAL const nk_uint nk_utfmin[NK_UTF_SIZE+1] = {0, 0, 0x80, 0x800, 0x10000};
7868 NK_GLOBAL const nk_uint nk_utfmax[NK_UTF_SIZE+1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
7869 
7870 NK_INTERN int
7871 nk_utf_validate(nk_rune *u, int i)
7872 {
7873  NK_ASSERT(u);
7874  if (!u) return 0;
7875  if (!NK_BETWEEN(*u, nk_utfmin[i], nk_utfmax[i]) ||
7876  NK_BETWEEN(*u, 0xD800, 0xDFFF))
7877  *u = NK_UTF_INVALID;
7878  for (i = 1; *u > nk_utfmax[i]; ++i);
7879  return i;
7880 }
7882 nk_utf_decode_byte(char c, int *i)
7883 {
7884  NK_ASSERT(i);
7885  if (!i) return 0;
7886  for(*i = 0; *i < (int)NK_LEN(nk_utfmask); ++(*i)) {
7887  if (((nk_byte)c & nk_utfmask[*i]) == nk_utfbyte[*i])
7888  return (nk_byte)(c & ~nk_utfmask[*i]);
7889  }
7890  return 0;
7891 }
7892 NK_API int
7893 nk_utf_decode(const char *c, nk_rune *u, int clen)
7894 {
7895  int i, j, len, type=0;
7896  nk_rune udecoded;
7897 
7898  NK_ASSERT(c);
7899  NK_ASSERT(u);
7900 
7901  if (!c || !u) return 0;
7902  if (!clen) return 0;
7903  *u = NK_UTF_INVALID;
7904 
7905  udecoded = nk_utf_decode_byte(c[0], &len);
7906  if (!NK_BETWEEN(len, 1, NK_UTF_SIZE))
7907  return 1;
7908 
7909  for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
7910  udecoded = (udecoded << 6) | nk_utf_decode_byte(c[i], &type);
7911  if (type != 0)
7912  return j;
7913  }
7914  if (j < len)
7915  return 0;
7916  *u = udecoded;
7917  nk_utf_validate(u, len);
7918  return len;
7919 }
7920 NK_INTERN char
7921 nk_utf_encode_byte(nk_rune u, int i)
7922 {
7923  return (char)((nk_utfbyte[i]) | ((nk_byte)u & ~nk_utfmask[i]));
7924 }
7925 NK_API int
7926 nk_utf_encode(nk_rune u, char *c, int clen)
7927 {
7928  int len, i;
7929  len = nk_utf_validate(&u, 0);
7930  if (clen < len || !len || len > NK_UTF_SIZE)
7931  return 0;
7932 
7933  for (i = len - 1; i != 0; --i) {
7934  c[i] = nk_utf_encode_byte(u, 0);
7935  u >>= 6;
7936  }
7937  c[0] = nk_utf_encode_byte(u, len);
7938  return len;
7939 }
7940 NK_API int
7941 nk_utf_len(const char *str, int len)
7942 {
7943  const char *text;
7944  int glyphs = 0;
7945  int text_len;
7946  int glyph_len;
7947  int src_len = 0;
7948  nk_rune unicode;
7949 
7950  NK_ASSERT(str);
7951  if (!str || !len) return 0;
7952 
7953  text = str;
7954  text_len = len;
7955  glyph_len = nk_utf_decode(text, &unicode, text_len);
7956  while (glyph_len && src_len < len) {
7957  glyphs++;
7958  src_len = src_len + glyph_len;
7959  glyph_len = nk_utf_decode(text + src_len, &unicode, text_len - src_len);
7960  }
7961  return glyphs;
7962 }
7963 NK_API const char*
7964 nk_utf_at(const char *buffer, int length, int index,
7965  nk_rune *unicode, int *len)
7966 {
7967  int i = 0;
7968  int src_len = 0;
7969  int glyph_len = 0;
7970  const char *text;
7971  int text_len;
7972 
7973  NK_ASSERT(buffer);
7974  NK_ASSERT(unicode);
7975  NK_ASSERT(len);
7976 
7977  if (!buffer || !unicode || !len) return 0;
7978  if (index < 0) {
7979  *unicode = NK_UTF_INVALID;
7980  *len = 0;
7981  return 0;
7982  }
7983 
7984  text = buffer;
7985  text_len = length;
7986  glyph_len = nk_utf_decode(text, unicode, text_len);
7987  while (glyph_len) {
7988  if (i == index) {
7989  *len = glyph_len;
7990  break;
7991  }
7992 
7993  i++;
7994  src_len = src_len + glyph_len;
7995  glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
7996  }
7997  if (i != index) return 0;
7998  return buffer + src_len;
7999 }
8000 
8001 
8002 
8003 
8004 
8005 /* ==============================================================
8006  *
8007  * BUFFER
8008  *
8009  * ===============================================================*/
8010 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
8011 NK_LIB void*
8012 nk_malloc(nk_handle unused, void *old,nk_size size)
8013 {
8014  NK_UNUSED(unused);
8015  NK_UNUSED(old);
8016  return malloc(size);
8017 }
8018 NK_LIB void
8019 nk_mfree(nk_handle unused, void *ptr)
8020 {
8021  NK_UNUSED(unused);
8022  free(ptr);
8023 }
8024 NK_API void
8025 nk_buffer_init_default(struct nk_buffer *buffer)
8026 {
8027  struct nk_allocator alloc;
8028  alloc.userdata.ptr = 0;
8029  alloc.alloc = nk_malloc;
8030  alloc.free = nk_mfree;
8031  nk_buffer_init(buffer, &alloc, NK_BUFFER_DEFAULT_INITIAL_SIZE);
8032 }
8033 #endif
8034 
8035 NK_API void
8036 nk_buffer_init(struct nk_buffer *b, const struct nk_allocator *a,
8037  nk_size initial_size)
8038 {
8039  NK_ASSERT(b);
8040  NK_ASSERT(a);
8041  NK_ASSERT(initial_size);
8042  if (!b || !a || !initial_size) return;
8043 
8044  nk_zero(b, sizeof(*b));
8045  b->type = NK_BUFFER_DYNAMIC;
8046  b->memory.ptr = a->alloc(a->userdata,0, initial_size);
8047  b->memory.size = initial_size;
8048  b->size = initial_size;
8049  b->grow_factor = 2.0f;
8050  b->pool = *a;
8051 }
8052 NK_API void
8053 nk_buffer_init_fixed(struct nk_buffer *b, void *m, nk_size size)
8054 {
8055  NK_ASSERT(b);
8056  NK_ASSERT(m);
8057  NK_ASSERT(size);
8058  if (!b || !m || !size) return;
8059 
8060  nk_zero(b, sizeof(*b));
8061  b->type = NK_BUFFER_FIXED;
8062  b->memory.ptr = m;
8063  b->memory.size = size;
8064  b->size = size;
8065 }
8066 NK_LIB void*
8067 nk_buffer_align(void *unaligned,
8068  nk_size align, nk_size *alignment,
8069  enum nk_buffer_allocation_type type)
8070 {
8071  void *memory = 0;
8072  switch (type) {
8073  default:
8074  case NK_BUFFER_MAX:
8075  case NK_BUFFER_FRONT:
8076  if (align) {
8077  memory = NK_ALIGN_PTR(unaligned, align);
8078  *alignment = (nk_size)((nk_byte*)memory - (nk_byte*)unaligned);
8079  } else {
8080  memory = unaligned;
8081  *alignment = 0;
8082  }
8083  break;
8084  case NK_BUFFER_BACK:
8085  if (align) {
8086  memory = NK_ALIGN_PTR_BACK(unaligned, align);
8087  *alignment = (nk_size)((nk_byte*)unaligned - (nk_byte*)memory);
8088  } else {
8089  memory = unaligned;
8090  *alignment = 0;
8091  }
8092  break;
8093  }
8094  return memory;
8095 }
8096 NK_LIB void*
8097 nk_buffer_realloc(struct nk_buffer *b, nk_size capacity, nk_size *size)
8098 {
8099  void *temp;
8100  nk_size buffer_size;
8101 
8102  NK_ASSERT(b);
8103  NK_ASSERT(size);
8104  if (!b || !size || !b->pool.alloc || !b->pool.free)
8105  return 0;
8106 
8107  buffer_size = b->memory.size;
8108  temp = b->pool.alloc(b->pool.userdata, b->memory.ptr, capacity);
8109  NK_ASSERT(temp);
8110  if (!temp) return 0;
8111 
8112  *size = capacity;
8113  if (temp != b->memory.ptr) {
8114  NK_MEMCPY(temp, b->memory.ptr, buffer_size);
8115  b->pool.free(b->pool.userdata, b->memory.ptr);
8116  }
8117 
8118  if (b->size == buffer_size) {
8119  /* no back buffer so just set correct size */
8120  b->size = capacity;
8121  return temp;
8122  } else {
8123  /* copy back buffer to the end of the new buffer */
8124  void *dst, *src;
8125  nk_size back_size;
8126  back_size = buffer_size - b->size;
8127  dst = nk_ptr_add(void, temp, capacity - back_size);
8128  src = nk_ptr_add(void, temp, b->size);
8129  NK_MEMCPY(dst, src, back_size);
8130  b->size = capacity - back_size;
8131  }
8132  return temp;
8133 }
8134 NK_LIB void*
8135 nk_buffer_alloc(struct nk_buffer *b, enum nk_buffer_allocation_type type,
8136  nk_size size, nk_size align)
8137 {
8138  int full;
8139  nk_size alignment;
8140  void *unaligned;
8141  void *memory;
8142 
8143  NK_ASSERT(b);
8144  NK_ASSERT(size);
8145  if (!b || !size) return 0;
8146  b->needed += size;
8147 
8148  /* calculate total size with needed alignment + size */
8149  if (type == NK_BUFFER_FRONT)
8150  unaligned = nk_ptr_add(void, b->memory.ptr, b->allocated);
8151  else unaligned = nk_ptr_add(void, b->memory.ptr, b->size - size);
8152  memory = nk_buffer_align(unaligned, align, &alignment, type);
8153 
8154  /* check if buffer has enough memory*/
8155  if (type == NK_BUFFER_FRONT)
8156  full = ((b->allocated + size + alignment) > b->size);
8157  else full = ((b->size - NK_MIN(b->size,(size + alignment))) <= b->allocated);
8158 
8159  if (full) {
8160  nk_size capacity;
8161  if (b->type != NK_BUFFER_DYNAMIC)
8162  return 0;
8163  NK_ASSERT(b->pool.alloc && b->pool.free);
8164  if (b->type != NK_BUFFER_DYNAMIC || !b->pool.alloc || !b->pool.free)
8165  return 0;
8166 
8167  /* buffer is full so allocate bigger buffer if dynamic */
8168  capacity = (nk_size)((float)b->memory.size * b->grow_factor);
8169  capacity = NK_MAX(capacity, nk_round_up_pow2((nk_uint)(b->allocated + size)));
8170  b->memory.ptr = nk_buffer_realloc(b, capacity, &b->memory.size);
8171  if (!b->memory.ptr) return 0;
8172 
8173  /* align newly allocated pointer */
8174  if (type == NK_BUFFER_FRONT)
8175  unaligned = nk_ptr_add(void, b->memory.ptr, b->allocated);
8176  else unaligned = nk_ptr_add(void, b->memory.ptr, b->size - size);
8177  memory = nk_buffer_align(unaligned, align, &alignment, type);
8178  }
8179  if (type == NK_BUFFER_FRONT)
8180  b->allocated += size + alignment;
8181  else b->size -= (size + alignment);
8182  b->needed += alignment;
8183  b->calls++;
8184  return memory;
8185 }
8186 NK_API void
8188  const void *memory, nk_size size, nk_size align)
8189 {
8190  void *mem = nk_buffer_alloc(b, type, size, align);
8191  if (!mem) return;
8192  NK_MEMCPY(mem, memory, size);
8193 }
8194 NK_API void
8195 nk_buffer_mark(struct nk_buffer *buffer, enum nk_buffer_allocation_type type)
8196 {
8197  NK_ASSERT(buffer);
8198  if (!buffer) return;
8199  buffer->marker[type].active = nk_true;
8200  if (type == NK_BUFFER_BACK)
8201  buffer->marker[type].offset = buffer->size;
8202  else buffer->marker[type].offset = buffer->allocated;
8203 }
8204 NK_API void
8205 nk_buffer_reset(struct nk_buffer *buffer, enum nk_buffer_allocation_type type)
8206 {
8207  NK_ASSERT(buffer);
8208  if (!buffer) return;
8209  if (type == NK_BUFFER_BACK) {
8210  /* reset back buffer either back to marker or empty */
8211  buffer->needed -= (buffer->memory.size - buffer->marker[type].offset);
8212  if (buffer->marker[type].active)
8213  buffer->size = buffer->marker[type].offset;
8214  else buffer->size = buffer->memory.size;
8215  buffer->marker[type].active = nk_false;
8216  } else {
8217  /* reset front buffer either back to back marker or empty */
8218  buffer->needed -= (buffer->allocated - buffer->marker[type].offset);
8219  if (buffer->marker[type].active)
8220  buffer->allocated = buffer->marker[type].offset;
8221  else buffer->allocated = 0;
8222  buffer->marker[type].active = nk_false;
8223  }
8224 }
8225 NK_API void
8226 nk_buffer_clear(struct nk_buffer *b)
8227 {
8228  NK_ASSERT(b);
8229  if (!b) return;
8230  b->allocated = 0;
8231  b->size = b->memory.size;
8232  b->calls = 0;
8233  b->needed = 0;
8234 }
8235 NK_API void
8236 nk_buffer_free(struct nk_buffer *b)
8237 {
8238  NK_ASSERT(b);
8239  if (!b || !b->memory.ptr) return;
8240  if (b->type == NK_BUFFER_FIXED) return;
8241  if (!b->pool.free) return;
8242  NK_ASSERT(b->pool.free);
8243  b->pool.free(b->pool.userdata, b->memory.ptr);
8244 }
8245 NK_API void
8246 nk_buffer_info(struct nk_memory_status *s, struct nk_buffer *b)
8247 {
8248  NK_ASSERT(b);
8249  NK_ASSERT(s);
8250  if (!s || !b) return;
8251  s->allocated = b->allocated;
8252  s->size = b->memory.size;
8253  s->needed = b->needed;
8254  s->memory = b->memory.ptr;
8255  s->calls = b->calls;
8256 }
8257 NK_API void*
8258 nk_buffer_memory(struct nk_buffer *buffer)
8259 {
8260  NK_ASSERT(buffer);
8261  if (!buffer) return 0;
8262  return buffer->memory.ptr;
8263 }
8264 NK_API const void*
8265 nk_buffer_memory_const(const struct nk_buffer *buffer)
8266 {
8267  NK_ASSERT(buffer);
8268  if (!buffer) return 0;
8269  return buffer->memory.ptr;
8270 }
8272 nk_buffer_total(struct nk_buffer *buffer)
8273 {
8274  NK_ASSERT(buffer);
8275  if (!buffer) return 0;
8276  return buffer->memory.size;
8277 }
8278 
8279 
8280 
8281 
8282 
8283 /* ===============================================================
8284  *
8285  * STRING
8286  *
8287  * ===============================================================*/
8288 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
8289 NK_API void
8290 nk_str_init_default(struct nk_str *str)
8291 {
8292  struct nk_allocator alloc;
8293  alloc.userdata.ptr = 0;
8294  alloc.alloc = nk_malloc;
8295  alloc.free = nk_mfree;
8296  nk_buffer_init(&str->buffer, &alloc, 32);
8297  str->len = 0;
8298 }
8299 #endif
8300 
8301 NK_API void
8302 nk_str_init(struct nk_str *str, const struct nk_allocator *alloc, nk_size size)
8303 {
8304  nk_buffer_init(&str->buffer, alloc, size);
8305  str->len = 0;
8306 }
8307 NK_API void
8308 nk_str_init_fixed(struct nk_str *str, void *memory, nk_size size)
8309 {
8310  nk_buffer_init_fixed(&str->buffer, memory, size);
8311  str->len = 0;
8312 }
8313 NK_API int
8314 nk_str_append_text_char(struct nk_str *s, const char *str, int len)
8315 {
8316  char *mem;
8317  NK_ASSERT(s);
8318  NK_ASSERT(str);
8319  if (!s || !str || !len) return 0;
8320  mem = (char*)nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len * sizeof(char), 0);
8321  if (!mem) return 0;
8322  NK_MEMCPY(mem, str, (nk_size)len * sizeof(char));
8323  s->len += nk_utf_len(str, len);
8324  return len;
8325 }
8326 NK_API int
8327 nk_str_append_str_char(struct nk_str *s, const char *str)
8328 {
8329  return nk_str_append_text_char(s, str, nk_strlen(str));
8330 }
8331 NK_API int
8332 nk_str_append_text_utf8(struct nk_str *str, const char *text, int len)
8333 {
8334  int i = 0;
8335  int byte_len = 0;
8336  nk_rune unicode;
8337  if (!str || !text || !len) return 0;
8338  for (i = 0; i < len; ++i)
8339  byte_len += nk_utf_decode(text+byte_len, &unicode, 4);
8340  nk_str_append_text_char(str, text, byte_len);
8341  return len;
8342 }
8343 NK_API int
8344 nk_str_append_str_utf8(struct nk_str *str, const char *text)
8345 {
8346  int runes = 0;
8347  int byte_len = 0;
8348  int num_runes = 0;
8349  int glyph_len = 0;
8350  nk_rune unicode;
8351  if (!str || !text) return 0;
8352 
8353  glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4);
8354  while (unicode != '\0' && glyph_len) {
8355  glyph_len = nk_utf_decode(text+byte_len, &unicode, 4);
8356  byte_len += glyph_len;
8357  num_runes++;
8358  }
8359  nk_str_append_text_char(str, text, byte_len);
8360  return runes;
8361 }
8362 NK_API int
8363 nk_str_append_text_runes(struct nk_str *str, const nk_rune *text, int len)
8364 {
8365  int i = 0;
8366  int byte_len = 0;
8367  nk_glyph glyph;
8368 
8369  NK_ASSERT(str);
8370  if (!str || !text || !len) return 0;
8371  for (i = 0; i < len; ++i) {
8372  byte_len = nk_utf_encode(text[i], glyph, NK_UTF_SIZE);
8373  if (!byte_len) break;
8374  nk_str_append_text_char(str, glyph, byte_len);
8375  }
8376  return len;
8377 }
8378 NK_API int
8379 nk_str_append_str_runes(struct nk_str *str, const nk_rune *runes)
8380 {
8381  int i = 0;
8382  nk_glyph glyph;
8383  int byte_len;
8384  NK_ASSERT(str);
8385  if (!str || !runes) return 0;
8386  while (runes[i] != '\0') {
8387  byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
8388  nk_str_append_text_char(str, glyph, byte_len);
8389  i++;
8390  }
8391  return i;
8392 }
8393 NK_API int
8394 nk_str_insert_at_char(struct nk_str *s, int pos, const char *str, int len)
8395 {
8396  int i;
8397  void *mem;
8398  char *src;
8399  char *dst;
8400 
8401  int copylen;
8402  NK_ASSERT(s);
8403  NK_ASSERT(str);
8404  NK_ASSERT(len >= 0);
8405  if (!s || !str || !len || (nk_size)pos > s->buffer.allocated) return 0;
8406  if ((s->buffer.allocated + (nk_size)len >= s->buffer.memory.size) &&
8407  (s->buffer.type == NK_BUFFER_FIXED)) return 0;
8408 
8409  copylen = (int)s->buffer.allocated - pos;
8410  if (!copylen) {
8411  nk_str_append_text_char(s, str, len);
8412  return 1;
8413  }
8414  mem = nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len * sizeof(char), 0);
8415  if (!mem) return 0;
8416 
8417  /* memmove */
8418  NK_ASSERT(((int)pos + (int)len + ((int)copylen - 1)) >= 0);
8419  NK_ASSERT(((int)pos + ((int)copylen - 1)) >= 0);
8420  dst = nk_ptr_add(char, s->buffer.memory.ptr, pos + len + (copylen - 1));
8421  src = nk_ptr_add(char, s->buffer.memory.ptr, pos + (copylen-1));
8422  for (i = 0; i < copylen; ++i) *dst-- = *src--;
8423  mem = nk_ptr_add(void, s->buffer.memory.ptr, pos);
8424  NK_MEMCPY(mem, str, (nk_size)len * sizeof(char));
8425  s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
8426  return 1;
8427 }
8428 NK_API int
8429 nk_str_insert_at_rune(struct nk_str *str, int pos, const char *cstr, int len)
8430 {
8431  int glyph_len;
8432  nk_rune unicode;
8433  const char *begin;
8434  const char *buffer;
8435 
8436  NK_ASSERT(str);
8437  NK_ASSERT(cstr);
8438  NK_ASSERT(len);
8439  if (!str || !cstr || !len) return 0;
8440  begin = nk_str_at_rune(str, pos, &unicode, &glyph_len);
8441  if (!str->len)
8442  return nk_str_append_text_char(str, cstr, len);
8443  buffer = nk_str_get_const(str);
8444  if (!begin) return 0;
8445  return nk_str_insert_at_char(str, (int)(begin - buffer), cstr, len);
8446 }
8447 NK_API int
8448 nk_str_insert_text_char(struct nk_str *str, int pos, const char *text, int len)
8449 {
8450  return nk_str_insert_text_utf8(str, pos, text, len);
8451 }
8452 NK_API int
8453 nk_str_insert_str_char(struct nk_str *str, int pos, const char *text)
8454 {
8455  return nk_str_insert_text_utf8(str, pos, text, nk_strlen(text));
8456 }
8457 NK_API int
8458 nk_str_insert_text_utf8(struct nk_str *str, int pos, const char *text, int len)
8459 {
8460  int i = 0;
8461  int byte_len = 0;
8462  nk_rune unicode;
8463 
8464  NK_ASSERT(str);
8465  NK_ASSERT(text);
8466  if (!str || !text || !len) return 0;
8467  for (i = 0; i < len; ++i)
8468  byte_len += nk_utf_decode(text+byte_len, &unicode, 4);
8469  nk_str_insert_at_rune(str, pos, text, byte_len);
8470  return len;
8471 }
8472 NK_API int
8473 nk_str_insert_str_utf8(struct nk_str *str, int pos, const char *text)
8474 {
8475  int runes = 0;
8476  int byte_len = 0;
8477  int num_runes = 0;
8478  int glyph_len = 0;
8479  nk_rune unicode;
8480  if (!str || !text) return 0;
8481 
8482  glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4);
8483  while (unicode != '\0' && glyph_len) {
8484  glyph_len = nk_utf_decode(text+byte_len, &unicode, 4);
8485  byte_len += glyph_len;
8486  num_runes++;
8487  }
8488  nk_str_insert_at_rune(str, pos, text, byte_len);
8489  return runes;
8490 }
8491 NK_API int
8492 nk_str_insert_text_runes(struct nk_str *str, int pos, const nk_rune *runes, int len)
8493 {
8494  int i = 0;
8495  int byte_len = 0;
8496  nk_glyph glyph;
8497 
8498  NK_ASSERT(str);
8499  if (!str || !runes || !len) return 0;
8500  for (i = 0; i < len; ++i) {
8501  byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
8502  if (!byte_len) break;
8503  nk_str_insert_at_rune(str, pos+i, glyph, byte_len);
8504  }
8505  return len;
8506 }
8507 NK_API int
8508 nk_str_insert_str_runes(struct nk_str *str, int pos, const nk_rune *runes)
8509 {
8510  int i = 0;
8511  nk_glyph glyph;
8512  int byte_len;
8513  NK_ASSERT(str);
8514  if (!str || !runes) return 0;
8515  while (runes[i] != '\0') {
8516  byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
8517  nk_str_insert_at_rune(str, pos+i, glyph, byte_len);
8518  i++;
8519  }
8520  return i;
8521 }
8522 NK_API void
8523 nk_str_remove_chars(struct nk_str *s, int len)
8524 {
8525  NK_ASSERT(s);
8526  NK_ASSERT(len >= 0);
8527  if (!s || len < 0 || (nk_size)len > s->buffer.allocated) return;
8528  NK_ASSERT(((int)s->buffer.allocated - (int)len) >= 0);
8529  s->buffer.allocated -= (nk_size)len;
8530  s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
8531 }
8532 NK_API void
8533 nk_str_remove_runes(struct nk_str *str, int len)
8534 {
8535  int index;
8536  const char *begin;
8537  const char *end;
8538  nk_rune unicode;
8539 
8540  NK_ASSERT(str);
8541  NK_ASSERT(len >= 0);
8542  if (!str || len < 0) return;
8543  if (len >= str->len) {
8544  str->len = 0;
8545  return;
8546  }
8547 
8548  index = str->len - len;
8549  begin = nk_str_at_rune(str, index, &unicode, &len);
8550  end = (const char*)str->buffer.memory.ptr + str->buffer.allocated;
8551  nk_str_remove_chars(str, (int)(end-begin)+1);
8552 }
8553 NK_API void
8554 nk_str_delete_chars(struct nk_str *s, int pos, int len)
8555 {
8556  NK_ASSERT(s);
8557  if (!s || !len || (nk_size)pos > s->buffer.allocated ||
8558  (nk_size)(pos + len) > s->buffer.allocated) return;
8559 
8560  if ((nk_size)(pos + len) < s->buffer.allocated) {
8561  /* memmove */
8562  char *dst = nk_ptr_add(char, s->buffer.memory.ptr, pos);
8563  char *src = nk_ptr_add(char, s->buffer.memory.ptr, pos + len);
8564  NK_MEMCPY(dst, src, s->buffer.allocated - (nk_size)(pos + len));
8565  NK_ASSERT(((int)s->buffer.allocated - (int)len) >= 0);
8566  s->buffer.allocated -= (nk_size)len;
8567  } else nk_str_remove_chars(s, len);
8568  s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
8569 }
8570 NK_API void
8571 nk_str_delete_runes(struct nk_str *s, int pos, int len)
8572 {
8573  char *temp;
8574  nk_rune unicode;
8575  char *begin;
8576  char *end;
8577  int unused;
8578 
8579  NK_ASSERT(s);
8580  NK_ASSERT(s->len >= pos + len);
8581  if (s->len < pos + len)
8582  len = NK_CLAMP(0, (s->len - pos), s->len);
8583  if (!len) return;
8584 
8585  temp = (char *)s->buffer.memory.ptr;
8586  begin = nk_str_at_rune(s, pos, &unicode, &unused);
8587  if (!begin) return;
8588  s->buffer.memory.ptr = begin;
8589  end = nk_str_at_rune(s, len, &unicode, &unused);
8590  s->buffer.memory.ptr = temp;
8591  if (!end) return;
8592  nk_str_delete_chars(s, (int)(begin - temp), (int)(end - begin));
8593 }
8594 NK_API char*
8595 nk_str_at_char(struct nk_str *s, int pos)
8596 {
8597  NK_ASSERT(s);
8598  if (!s || pos > (int)s->buffer.allocated) return 0;
8599  return nk_ptr_add(char, s->buffer.memory.ptr, pos);
8600 }
8601 NK_API char*
8602 nk_str_at_rune(struct nk_str *str, int pos, nk_rune *unicode, int *len)
8603 {
8604  int i = 0;
8605  int src_len = 0;
8606  int glyph_len = 0;
8607  char *text;
8608  int text_len;
8609 
8610  NK_ASSERT(str);
8611  NK_ASSERT(unicode);
8612  NK_ASSERT(len);
8613 
8614  if (!str || !unicode || !len) return 0;
8615  if (pos < 0) {
8616  *unicode = 0;
8617  *len = 0;
8618  return 0;
8619  }
8620 
8621  text = (char*)str->buffer.memory.ptr;
8622  text_len = (int)str->buffer.allocated;
8623  glyph_len = nk_utf_decode(text, unicode, text_len);
8624  while (glyph_len) {
8625  if (i == pos) {
8626  *len = glyph_len;
8627  break;
8628  }
8629 
8630  i++;
8631  src_len = src_len + glyph_len;
8632  glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
8633  }
8634  if (i != pos) return 0;
8635  return text + src_len;
8636 }
8637 NK_API const char*
8638 nk_str_at_char_const(const struct nk_str *s, int pos)
8639 {
8640  NK_ASSERT(s);
8641  if (!s || pos > (int)s->buffer.allocated) return 0;
8642  return nk_ptr_add(char, s->buffer.memory.ptr, pos);
8643 }
8644 NK_API const char*
8645 nk_str_at_const(const struct nk_str *str, int pos, nk_rune *unicode, int *len)
8646 {
8647  int i = 0;
8648  int src_len = 0;
8649  int glyph_len = 0;
8650  char *text;
8651  int text_len;
8652 
8653  NK_ASSERT(str);
8654  NK_ASSERT(unicode);
8655  NK_ASSERT(len);
8656 
8657  if (!str || !unicode || !len) return 0;
8658  if (pos < 0) {
8659  *unicode = 0;
8660  *len = 0;
8661  return 0;
8662  }
8663 
8664  text = (char*)str->buffer.memory.ptr;
8665  text_len = (int)str->buffer.allocated;
8666  glyph_len = nk_utf_decode(text, unicode, text_len);
8667  while (glyph_len) {
8668  if (i == pos) {
8669  *len = glyph_len;
8670  break;
8671  }
8672 
8673  i++;
8674  src_len = src_len + glyph_len;
8675  glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
8676  }
8677  if (i != pos) return 0;
8678  return text + src_len;
8679 }
8681 nk_str_rune_at(const struct nk_str *str, int pos)
8682 {
8683  int len;
8684  nk_rune unicode = 0;
8685  nk_str_at_const(str, pos, &unicode, &len);
8686  return unicode;
8687 }
8688 NK_API char*
8689 nk_str_get(struct nk_str *s)
8690 {
8691  NK_ASSERT(s);
8692  if (!s || !s->len || !s->buffer.allocated) return 0;
8693  return (char*)s->buffer.memory.ptr;
8694 }
8695 NK_API const char*
8696 nk_str_get_const(const struct nk_str *s)
8697 {
8698  NK_ASSERT(s);
8699  if (!s || !s->len || !s->buffer.allocated) return 0;
8700  return (const char*)s->buffer.memory.ptr;
8701 }
8702 NK_API int
8703 nk_str_len(struct nk_str *s)
8704 {
8705  NK_ASSERT(s);
8706  if (!s || !s->len || !s->buffer.allocated) return 0;
8707  return s->len;
8708 }
8709 NK_API int
8710 nk_str_len_char(struct nk_str *s)
8711 {
8712  NK_ASSERT(s);
8713  if (!s || !s->len || !s->buffer.allocated) return 0;
8714  return (int)s->buffer.allocated;
8715 }
8716 NK_API void
8717 nk_str_clear(struct nk_str *str)
8718 {
8719  NK_ASSERT(str);
8720  nk_buffer_clear(&str->buffer);
8721  str->len = 0;
8722 }
8723 NK_API void
8724 nk_str_free(struct nk_str *str)
8725 {
8726  NK_ASSERT(str);
8727  nk_buffer_free(&str->buffer);
8728  str->len = 0;
8729 }
8730 
8731 
8732 
8733 
8734 
8735 /* ==============================================================
8736  *
8737  * DRAW
8738  *
8739  * ===============================================================*/
8740 NK_LIB void
8741 nk_command_buffer_init(struct nk_command_buffer *cb,
8742  struct nk_buffer *b, enum nk_command_clipping clip)
8743 {
8744  NK_ASSERT(cb);
8745  NK_ASSERT(b);
8746  if (!cb || !b) return;
8747  cb->base = b;
8748  cb->use_clipping = (int)clip;
8749  cb->begin = b->allocated;
8750  cb->end = b->allocated;
8751  cb->last = b->allocated;
8752 }
8753 NK_LIB void
8754 nk_command_buffer_reset(struct nk_command_buffer *b)
8755 {
8756  NK_ASSERT(b);
8757  if (!b) return;
8758  b->begin = 0;
8759  b->end = 0;
8760  b->last = 0;
8761  b->clip = nk_null_rect;
8762 #ifdef NK_INCLUDE_COMMAND_USERDATA
8763  b->userdata.ptr = 0;
8764 #endif
8765 }
8766 NK_LIB void*
8767 nk_command_buffer_push(struct nk_command_buffer* b,
8768  enum nk_command_type t, nk_size size)
8769 {
8770  NK_STORAGE const nk_size align = NK_ALIGNOF(struct nk_command);
8771  struct nk_command *cmd;
8772  nk_size alignment;
8773  void *unaligned;
8774  void *memory;
8775 
8776  NK_ASSERT(b);
8777  NK_ASSERT(b->base);
8778  if (!b) return 0;
8779  cmd = (struct nk_command*)nk_buffer_alloc(b->base,NK_BUFFER_FRONT,size,align);
8780  if (!cmd) return 0;
8781 
8782  /* make sure the offset to the next command is aligned */
8783  b->last = (nk_size)((nk_byte*)cmd - (nk_byte*)b->base->memory.ptr);
8784  unaligned = (nk_byte*)cmd + size;
8785  memory = NK_ALIGN_PTR(unaligned, align);
8786  alignment = (nk_size)((nk_byte*)memory - (nk_byte*)unaligned);
8787 #ifdef NK_ZERO_COMMAND_MEMORY
8788  NK_MEMSET(cmd, 0, size + alignment);
8789 #endif
8790 
8791  cmd->type = t;
8792  cmd->next = b->base->allocated + alignment;
8793 #ifdef NK_INCLUDE_COMMAND_USERDATA
8794  cmd->userdata = b->userdata;
8795 #endif
8796  b->end = cmd->next;
8797  return cmd;
8798 }
8799 NK_API void
8800 nk_push_scissor(struct nk_command_buffer *b, struct nk_rect r)
8801 {
8802  struct nk_command_scissor *cmd;
8803  NK_ASSERT(b);
8804  if (!b) return;
8805 
8806  b->clip.x = r.x;
8807  b->clip.y = r.y;
8808  b->clip.w = r.w;
8809  b->clip.h = r.h;
8810  cmd = (struct nk_command_scissor*)
8811  nk_command_buffer_push(b, NK_COMMAND_SCISSOR, sizeof(*cmd));
8812 
8813  if (!cmd) return;
8814  cmd->x = (short)r.x;
8815  cmd->y = (short)r.y;
8816  cmd->w = (unsigned short)NK_MAX(0, r.w);
8817  cmd->h = (unsigned short)NK_MAX(0, r.h);
8818 }
8819 NK_API void
8820 nk_stroke_line(struct nk_command_buffer *b, float x0, float y0,
8821  float x1, float y1, float line_thickness, struct nk_color c)
8822 {
8823  struct nk_command_line *cmd;
8824  NK_ASSERT(b);
8825  if (!b || line_thickness <= 0) return;
8826  cmd = (struct nk_command_line*)
8827  nk_command_buffer_push(b, NK_COMMAND_LINE, sizeof(*cmd));
8828  if (!cmd) return;
8829  cmd->line_thickness = (unsigned short)line_thickness;
8830  cmd->begin.x = (short)x0;
8831  cmd->begin.y = (short)y0;
8832  cmd->end.x = (short)x1;
8833  cmd->end.y = (short)y1;
8834  cmd->color = c;
8835 }
8836 NK_API void
8837 nk_stroke_curve(struct nk_command_buffer *b, float ax, float ay,
8838  float ctrl0x, float ctrl0y, float ctrl1x, float ctrl1y,
8839  float bx, float by, float line_thickness, struct nk_color col)
8840 {
8841  struct nk_command_curve *cmd;
8842  NK_ASSERT(b);
8843  if (!b || col.a == 0 || line_thickness <= 0) return;
8844 
8845  cmd = (struct nk_command_curve*)
8846  nk_command_buffer_push(b, NK_COMMAND_CURVE, sizeof(*cmd));
8847  if (!cmd) return;
8848  cmd->line_thickness = (unsigned short)line_thickness;
8849  cmd->begin.x = (short)ax;
8850  cmd->begin.y = (short)ay;
8851  cmd->ctrl[0].x = (short)ctrl0x;
8852  cmd->ctrl[0].y = (short)ctrl0y;
8853  cmd->ctrl[1].x = (short)ctrl1x;
8854  cmd->ctrl[1].y = (short)ctrl1y;
8855  cmd->end.x = (short)bx;
8856  cmd->end.y = (short)by;
8857  cmd->color = col;
8858 }
8859 NK_API void
8860 nk_stroke_rect(struct nk_command_buffer *b, struct nk_rect rect,
8861  float rounding, float line_thickness, struct nk_color c)
8862 {
8863  struct nk_command_rect *cmd;
8864  NK_ASSERT(b);
8865  if (!b || c.a == 0 || rect.w == 0 || rect.h == 0 || line_thickness <= 0) return;
8866  if (b->use_clipping) {
8867  const struct nk_rect *clip = &b->clip;
8868  if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
8869  clip->x, clip->y, clip->w, clip->h)) return;
8870  }
8871  cmd = (struct nk_command_rect*)
8872  nk_command_buffer_push(b, NK_COMMAND_RECT, sizeof(*cmd));
8873  if (!cmd) return;
8874  cmd->rounding = (unsigned short)rounding;
8875  cmd->line_thickness = (unsigned short)line_thickness;
8876  cmd->x = (short)rect.x;
8877  cmd->y = (short)rect.y;
8878  cmd->w = (unsigned short)NK_MAX(0, rect.w);
8879  cmd->h = (unsigned short)NK_MAX(0, rect.h);
8880  cmd->color = c;
8881 }
8882 NK_API void
8883 nk_fill_rect(struct nk_command_buffer *b, struct nk_rect rect,
8884  float rounding, struct nk_color c)
8885 {
8886  struct nk_command_rect_filled *cmd;
8887  NK_ASSERT(b);
8888  if (!b || c.a == 0 || rect.w == 0 || rect.h == 0) return;
8889  if (b->use_clipping) {
8890  const struct nk_rect *clip = &b->clip;
8891  if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
8892  clip->x, clip->y, clip->w, clip->h)) return;
8893  }
8894 
8895  cmd = (struct nk_command_rect_filled*)
8896  nk_command_buffer_push(b, NK_COMMAND_RECT_FILLED, sizeof(*cmd));
8897  if (!cmd) return;
8898  cmd->rounding = (unsigned short)rounding;
8899  cmd->x = (short)rect.x;
8900  cmd->y = (short)rect.y;
8901  cmd->w = (unsigned short)NK_MAX(0, rect.w);
8902  cmd->h = (unsigned short)NK_MAX(0, rect.h);
8903  cmd->color = c;
8904 }
8905 NK_API void
8906 nk_fill_rect_multi_color(struct nk_command_buffer *b, struct nk_rect rect,
8907  struct nk_color left, struct nk_color top, struct nk_color right,
8908  struct nk_color bottom)
8909 {
8910  struct nk_command_rect_multi_color *cmd;
8911  NK_ASSERT(b);
8912  if (!b || rect.w == 0 || rect.h == 0) return;
8913  if (b->use_clipping) {
8914  const struct nk_rect *clip = &b->clip;
8915  if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
8916  clip->x, clip->y, clip->w, clip->h)) return;
8917  }
8918 
8919  cmd = (struct nk_command_rect_multi_color*)
8920  nk_command_buffer_push(b, NK_COMMAND_RECT_MULTI_COLOR, sizeof(*cmd));
8921  if (!cmd) return;
8922  cmd->x = (short)rect.x;
8923  cmd->y = (short)rect.y;
8924  cmd->w = (unsigned short)NK_MAX(0, rect.w);
8925  cmd->h = (unsigned short)NK_MAX(0, rect.h);
8926  cmd->left = left;
8927  cmd->top = top;
8928  cmd->right = right;
8929  cmd->bottom = bottom;
8930 }
8931 NK_API void
8932 nk_stroke_circle(struct nk_command_buffer *b, struct nk_rect r,
8933  float line_thickness, struct nk_color c)
8934 {
8935  struct nk_command_circle *cmd;
8936  if (!b || r.w == 0 || r.h == 0 || line_thickness <= 0) return;
8937  if (b->use_clipping) {
8938  const struct nk_rect *clip = &b->clip;
8939  if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h))
8940  return;
8941  }
8942 
8943  cmd = (struct nk_command_circle*)
8944  nk_command_buffer_push(b, NK_COMMAND_CIRCLE, sizeof(*cmd));
8945  if (!cmd) return;
8946  cmd->line_thickness = (unsigned short)line_thickness;
8947  cmd->x = (short)r.x;
8948  cmd->y = (short)r.y;
8949  cmd->w = (unsigned short)NK_MAX(r.w, 0);
8950  cmd->h = (unsigned short)NK_MAX(r.h, 0);
8951  cmd->color = c;
8952 }
8953 NK_API void
8954 nk_fill_circle(struct nk_command_buffer *b, struct nk_rect r, struct nk_color c)
8955 {
8956  struct nk_command_circle_filled *cmd;
8957  NK_ASSERT(b);
8958  if (!b || c.a == 0 || r.w == 0 || r.h == 0) return;
8959  if (b->use_clipping) {
8960  const struct nk_rect *clip = &b->clip;
8961  if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h))
8962  return;
8963  }
8964 
8965  cmd = (struct nk_command_circle_filled*)
8966  nk_command_buffer_push(b, NK_COMMAND_CIRCLE_FILLED, sizeof(*cmd));
8967  if (!cmd) return;
8968  cmd->x = (short)r.x;
8969  cmd->y = (short)r.y;
8970  cmd->w = (unsigned short)NK_MAX(r.w, 0);
8971  cmd->h = (unsigned short)NK_MAX(r.h, 0);
8972  cmd->color = c;
8973 }
8974 NK_API void
8975 nk_stroke_arc(struct nk_command_buffer *b, float cx, float cy, float radius,
8976  float a_min, float a_max, float line_thickness, struct nk_color c)
8977 {
8978  struct nk_command_arc *cmd;
8979  if (!b || c.a == 0 || line_thickness <= 0) return;
8980  cmd = (struct nk_command_arc*)
8981  nk_command_buffer_push(b, NK_COMMAND_ARC, sizeof(*cmd));
8982  if (!cmd) return;
8983  cmd->line_thickness = (unsigned short)line_thickness;
8984  cmd->cx = (short)cx;
8985  cmd->cy = (short)cy;
8986  cmd->r = (unsigned short)radius;
8987  cmd->a[0] = a_min;
8988  cmd->a[1] = a_max;
8989  cmd->color = c;
8990 }
8991 NK_API void
8992 nk_fill_arc(struct nk_command_buffer *b, float cx, float cy, float radius,
8993  float a_min, float a_max, struct nk_color c)
8994 {
8995  struct nk_command_arc_filled *cmd;
8996  NK_ASSERT(b);
8997  if (!b || c.a == 0) return;
8998  cmd = (struct nk_command_arc_filled*)
8999  nk_command_buffer_push(b, NK_COMMAND_ARC_FILLED, sizeof(*cmd));
9000  if (!cmd) return;
9001  cmd->cx = (short)cx;
9002  cmd->cy = (short)cy;
9003  cmd->r = (unsigned short)radius;
9004  cmd->a[0] = a_min;
9005  cmd->a[1] = a_max;
9006  cmd->color = c;
9007 }
9008 NK_API void
9009 nk_stroke_triangle(struct nk_command_buffer *b, float x0, float y0, float x1,
9010  float y1, float x2, float y2, float line_thickness, struct nk_color c)
9011 {
9012  struct nk_command_triangle *cmd;
9013  NK_ASSERT(b);
9014  if (!b || c.a == 0 || line_thickness <= 0) return;
9015  if (b->use_clipping) {
9016  const struct nk_rect *clip = &b->clip;
9017  if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) &&
9018  !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) &&
9019  !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h))
9020  return;
9021  }
9022 
9023  cmd = (struct nk_command_triangle*)
9024  nk_command_buffer_push(b, NK_COMMAND_TRIANGLE, sizeof(*cmd));
9025  if (!cmd) return;
9026  cmd->line_thickness = (unsigned short)line_thickness;
9027  cmd->a.x = (short)x0;
9028  cmd->a.y = (short)y0;
9029  cmd->b.x = (short)x1;
9030  cmd->b.y = (short)y1;
9031  cmd->c.x = (short)x2;
9032  cmd->c.y = (short)y2;
9033  cmd->color = c;
9034 }
9035 NK_API void
9036 nk_fill_triangle(struct nk_command_buffer *b, float x0, float y0, float x1,
9037  float y1, float x2, float y2, struct nk_color c)
9038 {
9039  struct nk_command_triangle_filled *cmd;
9040  NK_ASSERT(b);
9041  if (!b || c.a == 0) return;
9042  if (!b) return;
9043  if (b->use_clipping) {
9044  const struct nk_rect *clip = &b->clip;
9045  if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) &&
9046  !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) &&
9047  !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h))
9048  return;
9049  }
9050 
9051  cmd = (struct nk_command_triangle_filled*)
9052  nk_command_buffer_push(b, NK_COMMAND_TRIANGLE_FILLED, sizeof(*cmd));
9053  if (!cmd) return;
9054  cmd->a.x = (short)x0;
9055  cmd->a.y = (short)y0;
9056  cmd->b.x = (short)x1;
9057  cmd->b.y = (short)y1;
9058  cmd->c.x = (short)x2;
9059  cmd->c.y = (short)y2;
9060  cmd->color = c;
9061 }
9062 NK_API void
9063 nk_stroke_polygon(struct nk_command_buffer *b, float *points, int point_count,
9064  float line_thickness, struct nk_color col)
9065 {
9066  int i;
9067  nk_size size = 0;
9068  struct nk_command_polygon *cmd;
9069 
9070  NK_ASSERT(b);
9071  if (!b || col.a == 0 || line_thickness <= 0) return;
9072  size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
9073  cmd = (struct nk_command_polygon*) nk_command_buffer_push(b, NK_COMMAND_POLYGON, size);
9074  if (!cmd) return;
9075  cmd->color = col;
9076  cmd->line_thickness = (unsigned short)line_thickness;
9077  cmd->point_count = (unsigned short)point_count;
9078  for (i = 0; i < point_count; ++i) {
9079  cmd->points[i].x = (short)points[i*2];
9080  cmd->points[i].y = (short)points[i*2+1];
9081  }
9082 }
9083 NK_API void
9084 nk_fill_polygon(struct nk_command_buffer *b, float *points, int point_count,
9085  struct nk_color col)
9086 {
9087  int i;
9088  nk_size size = 0;
9089  struct nk_command_polygon_filled *cmd;
9090 
9091  NK_ASSERT(b);
9092  if (!b || col.a == 0) return;
9093  size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
9094  cmd = (struct nk_command_polygon_filled*)
9095  nk_command_buffer_push(b, NK_COMMAND_POLYGON_FILLED, size);
9096  if (!cmd) return;
9097  cmd->color = col;
9098  cmd->point_count = (unsigned short)point_count;
9099  for (i = 0; i < point_count; ++i) {
9100  cmd->points[i].x = (short)points[i*2+0];
9101  cmd->points[i].y = (short)points[i*2+1];
9102  }
9103 }
9104 NK_API void
9106  float line_thickness, struct nk_color col)
9107 {
9108  int i;
9109  nk_size size = 0;
9110  struct nk_command_polyline *cmd;
9111 
9112  NK_ASSERT(b);
9113  if (!b || col.a == 0 || line_thickness <= 0) return;
9114  size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
9115  cmd = (struct nk_command_polyline*) nk_command_buffer_push(b, NK_COMMAND_POLYLINE, size);
9116  if (!cmd) return;
9117  cmd->color = col;
9118  cmd->point_count = (unsigned short)point_count;
9119  cmd->line_thickness = (unsigned short)line_thickness;
9120  for (i = 0; i < point_count; ++i) {
9121  cmd->points[i].x = (short)points[i*2];
9122  cmd->points[i].y = (short)points[i*2+1];
9123  }
9124 }
9125 NK_API void
9126 nk_draw_image(struct nk_command_buffer *b, struct nk_rect r,
9127  const struct nk_image *img, struct nk_color col)
9128 {
9129  struct nk_command_image *cmd;
9130  NK_ASSERT(b);
9131  if (!b) return;
9132  if (b->use_clipping) {
9133  const struct nk_rect *c = &b->clip;
9134  if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h))
9135  return;
9136  }
9137 
9138  cmd = (struct nk_command_image*)
9139  nk_command_buffer_push(b, NK_COMMAND_IMAGE, sizeof(*cmd));
9140  if (!cmd) return;
9141  cmd->x = (short)r.x;
9142  cmd->y = (short)r.y;
9143  cmd->w = (unsigned short)NK_MAX(0, r.w);
9144  cmd->h = (unsigned short)NK_MAX(0, r.h);
9145  cmd->img = *img;
9146  cmd->col = col;
9147 }
9148 NK_API void
9149 nk_push_custom(struct nk_command_buffer *b, struct nk_rect r,
9151 {
9152  struct nk_command_custom *cmd;
9153  NK_ASSERT(b);
9154  if (!b) return;
9155  if (b->use_clipping) {
9156  const struct nk_rect *c = &b->clip;
9157  if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h))
9158  return;
9159  }
9160 
9161  cmd = (struct nk_command_custom*)
9162  nk_command_buffer_push(b, NK_COMMAND_CUSTOM, sizeof(*cmd));
9163  if (!cmd) return;
9164  cmd->x = (short)r.x;
9165  cmd->y = (short)r.y;
9166  cmd->w = (unsigned short)NK_MAX(0, r.w);
9167  cmd->h = (unsigned short)NK_MAX(0, r.h);
9168  cmd->callback_data = usr;
9169  cmd->callback = cb;
9170 }
9171 NK_API void
9172 nk_draw_text(struct nk_command_buffer *b, struct nk_rect r,
9173  const char *string, int length, const struct nk_user_font *font,
9174  struct nk_color bg, struct nk_color fg)
9175 {
9176  float text_width = 0;
9177  struct nk_command_text *cmd;
9178 
9179  NK_ASSERT(b);
9180  NK_ASSERT(font);
9181  if (!b || !string || !length || (bg.a == 0 && fg.a == 0)) return;
9182  if (b->use_clipping) {
9183  const struct nk_rect *c = &b->clip;
9184  if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h))
9185  return;
9186  }
9187 
9188  /* make sure text fits inside bounds */
9189  text_width = font->width(font->userdata, font->height, string, length);
9190  if (text_width > r.w){
9191  int glyphs = 0;
9192  float txt_width = (float)text_width;
9193  length = nk_text_clamp(font, string, length, r.w, &glyphs, &txt_width, 0,0);
9194  }
9195 
9196  if (!length) return;
9197  cmd = (struct nk_command_text*)
9198  nk_command_buffer_push(b, NK_COMMAND_TEXT, sizeof(*cmd) + (nk_size)(length + 1));
9199  if (!cmd) return;
9200  cmd->x = (short)r.x;
9201  cmd->y = (short)r.y;
9202  cmd->w = (unsigned short)r.w;
9203  cmd->h = (unsigned short)r.h;
9204  cmd->background = bg;
9205  cmd->foreground = fg;
9206  cmd->font = font;
9207  cmd->length = length;
9208  cmd->height = font->height;
9209  NK_MEMCPY(cmd->string, string, (nk_size)length);
9210  cmd->string[length] = '\0';
9211 }
9212 
9213 
9214 
9215 
9216 
9217 /* ===============================================================
9218  *
9219  * VERTEX
9220  *
9221  * ===============================================================*/
9222 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
9223 NK_API void
9224 nk_draw_list_init(struct nk_draw_list *list)
9225 {
9226  nk_size i = 0;
9227  NK_ASSERT(list);
9228  if (!list) return;
9229  nk_zero(list, sizeof(*list));
9230  for (i = 0; i < NK_LEN(list->circle_vtx); ++i) {
9231  const float a = ((float)i / (float)NK_LEN(list->circle_vtx)) * 2 * NK_PI;
9232  list->circle_vtx[i].x = (float)NK_COS(a);
9233  list->circle_vtx[i].y = (float)NK_SIN(a);
9234  }
9235 }
9236 NK_API void
9237 nk_draw_list_setup(struct nk_draw_list *canvas, const struct nk_convert_config *config,
9238  struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements,
9239  enum nk_anti_aliasing line_aa, enum nk_anti_aliasing shape_aa)
9240 {
9241  NK_ASSERT(canvas);
9242  NK_ASSERT(config);
9243  NK_ASSERT(cmds);
9244  NK_ASSERT(vertices);
9245  NK_ASSERT(elements);
9246  if (!canvas || !config || !cmds || !vertices || !elements)
9247  return;
9248 
9249  canvas->buffer = cmds;
9250  canvas->config = *config;
9251  canvas->elements = elements;
9252  canvas->vertices = vertices;
9253  canvas->line_AA = line_aa;
9254  canvas->shape_AA = shape_aa;
9255  canvas->clip_rect = nk_null_rect;
9256 
9257  canvas->cmd_offset = 0;
9258  canvas->element_count = 0;
9259  canvas->vertex_count = 0;
9260  canvas->cmd_offset = 0;
9261  canvas->cmd_count = 0;
9262  canvas->path_count = 0;
9263 }
9264 NK_API const struct nk_draw_command*
9265 nk__draw_list_begin(const struct nk_draw_list *canvas, const struct nk_buffer *buffer)
9266 {
9267  nk_byte *memory;
9268  nk_size offset;
9269  const struct nk_draw_command *cmd;
9270 
9271  NK_ASSERT(buffer);
9272  if (!buffer || !buffer->size || !canvas->cmd_count)
9273  return 0;
9274 
9275  memory = (nk_byte*)buffer->memory.ptr;
9276  offset = buffer->memory.size - canvas->cmd_offset;
9277  cmd = nk_ptr_add(const struct nk_draw_command, memory, offset);
9278  return cmd;
9279 }
9280 NK_API const struct nk_draw_command*
9281 nk__draw_list_end(const struct nk_draw_list *canvas, const struct nk_buffer *buffer)
9282 {
9283  nk_size size;
9284  nk_size offset;
9285  nk_byte *memory;
9286  const struct nk_draw_command *end;
9287 
9288  NK_ASSERT(buffer);
9289  NK_ASSERT(canvas);
9290  if (!buffer || !canvas)
9291  return 0;
9292 
9293  memory = (nk_byte*)buffer->memory.ptr;
9294  size = buffer->memory.size;
9295  offset = size - canvas->cmd_offset;
9296  end = nk_ptr_add(const struct nk_draw_command, memory, offset);
9297  end -= (canvas->cmd_count-1);
9298  return end;
9299 }
9300 NK_API const struct nk_draw_command*
9301 nk__draw_list_next(const struct nk_draw_command *cmd,
9302  const struct nk_buffer *buffer, const struct nk_draw_list *canvas)
9303 {
9304  const struct nk_draw_command *end;
9305  NK_ASSERT(buffer);
9306  NK_ASSERT(canvas);
9307  if (!cmd || !buffer || !canvas)
9308  return 0;
9309 
9310  end = nk__draw_list_end(canvas, buffer);
9311  if (cmd <= end) return 0;
9312  return (cmd-1);
9313 }
9314 NK_INTERN struct nk_vec2*
9315 nk_draw_list_alloc_path(struct nk_draw_list *list, int count)
9316 {
9317  struct nk_vec2 *points;
9318  NK_STORAGE const nk_size point_align = NK_ALIGNOF(struct nk_vec2);
9319  NK_STORAGE const nk_size point_size = sizeof(struct nk_vec2);
9320  points = (struct nk_vec2*)
9321  nk_buffer_alloc(list->buffer, NK_BUFFER_FRONT,
9322  point_size * (nk_size)count, point_align);
9323 
9324  if (!points) return 0;
9325  if (!list->path_offset) {
9326  void *memory = nk_buffer_memory(list->buffer);
9327  list->path_offset = (unsigned int)((nk_byte*)points - (nk_byte*)memory);
9328  }
9329  list->path_count += (unsigned int)count;
9330  return points;
9331 }
9332 NK_INTERN struct nk_vec2
9333 nk_draw_list_path_last(struct nk_draw_list *list)
9334 {
9335  void *memory;
9336  struct nk_vec2 *point;
9337  NK_ASSERT(list->path_count);
9338  memory = nk_buffer_memory(list->buffer);
9339  point = nk_ptr_add(struct nk_vec2, memory, list->path_offset);
9340  point += (list->path_count-1);
9341  return *point;
9342 }
9343 NK_INTERN struct nk_draw_command*
9344 nk_draw_list_push_command(struct nk_draw_list *list, struct nk_rect clip,
9345  nk_handle texture)
9346 {
9347  NK_STORAGE const nk_size cmd_align = NK_ALIGNOF(struct nk_draw_command);
9348  NK_STORAGE const nk_size cmd_size = sizeof(struct nk_draw_command);
9349  struct nk_draw_command *cmd;
9350 
9351  NK_ASSERT(list);
9352  cmd = (struct nk_draw_command*)
9353  nk_buffer_alloc(list->buffer, NK_BUFFER_BACK, cmd_size, cmd_align);
9354 
9355  if (!cmd) return 0;
9356  if (!list->cmd_count) {
9357  nk_byte *memory = (nk_byte*)nk_buffer_memory(list->buffer);
9358  nk_size total = nk_buffer_total(list->buffer);
9359  memory = nk_ptr_add(nk_byte, memory, total);
9360  list->cmd_offset = (nk_size)(memory - (nk_byte*)cmd);
9361  }
9362 
9363  cmd->elem_count = 0;
9364  cmd->clip_rect = clip;
9365  cmd->texture = texture;
9366 #ifdef NK_INCLUDE_COMMAND_USERDATA
9367  cmd->userdata = list->userdata;
9368 #endif
9369 
9370  list->cmd_count++;
9371  list->clip_rect = clip;
9372  return cmd;
9373 }
9374 NK_INTERN struct nk_draw_command*
9375 nk_draw_list_command_last(struct nk_draw_list *list)
9376 {
9377  void *memory;
9378  nk_size size;
9379  struct nk_draw_command *cmd;
9380  NK_ASSERT(list->cmd_count);
9381 
9382  memory = nk_buffer_memory(list->buffer);
9383  size = nk_buffer_total(list->buffer);
9384  cmd = nk_ptr_add(struct nk_draw_command, memory, size - list->cmd_offset);
9385  return (cmd - (list->cmd_count-1));
9386 }
9387 NK_INTERN void
9388 nk_draw_list_add_clip(struct nk_draw_list *list, struct nk_rect rect)
9389 {
9390  NK_ASSERT(list);
9391  if (!list) return;
9392  if (!list->cmd_count) {
9393  nk_draw_list_push_command(list, rect, list->config.null.texture);
9394  } else {
9395  struct nk_draw_command *prev = nk_draw_list_command_last(list);
9396  if (prev->elem_count == 0)
9397  prev->clip_rect = rect;
9398  nk_draw_list_push_command(list, rect, prev->texture);
9399  }
9400 }
9401 NK_INTERN void
9402 nk_draw_list_push_image(struct nk_draw_list *list, nk_handle texture)
9403 {
9404  NK_ASSERT(list);
9405  if (!list) return;
9406  if (!list->cmd_count) {
9407  nk_draw_list_push_command(list, nk_null_rect, texture);
9408  } else {
9409  struct nk_draw_command *prev = nk_draw_list_command_last(list);
9410  if (prev->elem_count == 0) {
9411  prev->texture = texture;
9412  #ifdef NK_INCLUDE_COMMAND_USERDATA
9413  prev->userdata = list->userdata;
9414  #endif
9415  } else if (prev->texture.id != texture.id
9416  #ifdef NK_INCLUDE_COMMAND_USERDATA
9417  || prev->userdata.id != list->userdata.id
9418  #endif
9419  ) nk_draw_list_push_command(list, prev->clip_rect, texture);
9420  }
9421 }
9422 #ifdef NK_INCLUDE_COMMAND_USERDATA
9423 NK_API void
9424 nk_draw_list_push_userdata(struct nk_draw_list *list, nk_handle userdata)
9425 {
9426  list->userdata = userdata;
9427 }
9428 #endif
9429 NK_INTERN void*
9430 nk_draw_list_alloc_vertices(struct nk_draw_list *list, nk_size count)
9431 {
9432  void *vtx;
9433  NK_ASSERT(list);
9434  if (!list) return 0;
9435  vtx = nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT,
9436  list->config.vertex_size*count, list->config.vertex_alignment);
9437  if (!vtx) return 0;
9438  list->vertex_count += (unsigned int)count;
9439 
9440  /* This assert triggers because your are drawing a lot of stuff and nuklear
9441  * defined `nk_draw_index` as `nk_ushort` to safe space be default.
9442  *
9443  * So you reached the maximum number of indicies or rather vertexes.
9444  * To solve this issue please change typdef `nk_draw_index` to `nk_uint`
9445  * and don't forget to specify the new element size in your drawing
9446  * backend (OpenGL, DirectX, ...). For example in OpenGL for `glDrawElements`
9447  * instead of specifing `GL_UNSIGNED_SHORT` you have to define `GL_UNSIGNED_INT`.
9448  * Sorry for the inconvenience. */
9449  if(sizeof(nk_draw_index)==2) NK_ASSERT((list->vertex_count < NK_USHORT_MAX &&
9450  "To many verticies for 16-bit vertex indicies. Please read comment above on how to solve this problem"));
9451  return vtx;
9452 }
9453 NK_INTERN nk_draw_index*
9454 nk_draw_list_alloc_elements(struct nk_draw_list *list, nk_size count)
9455 {
9456  nk_draw_index *ids;
9457  struct nk_draw_command *cmd;
9458  NK_STORAGE const nk_size elem_align = NK_ALIGNOF(nk_draw_index);
9459  NK_STORAGE const nk_size elem_size = sizeof(nk_draw_index);
9460  NK_ASSERT(list);
9461  if (!list) return 0;
9462 
9463  ids = (nk_draw_index*)
9464  nk_buffer_alloc(list->elements, NK_BUFFER_FRONT, elem_size*count, elem_align);
9465  if (!ids) return 0;
9466  cmd = nk_draw_list_command_last(list);
9467  list->element_count += (unsigned int)count;
9468  cmd->elem_count += (unsigned int)count;
9469  return ids;
9470 }
9471 NK_INTERN int
9472 nk_draw_vertex_layout_element_is_end_of_layout(
9473  const struct nk_draw_vertex_layout_element *element)
9474 {
9475  return (element->attribute == NK_VERTEX_ATTRIBUTE_COUNT ||
9476  element->format == NK_FORMAT_COUNT);
9477 }
9478 NK_INTERN void
9479 nk_draw_vertex_color(void *attr, const float *vals,
9480  enum nk_draw_vertex_layout_format format)
9481 {
9482  /* if this triggers you tried to provide a value format for a color */
9483  float val[4];
9484  NK_ASSERT(format >= NK_FORMAT_COLOR_BEGIN);
9485  NK_ASSERT(format <= NK_FORMAT_COLOR_END);
9486  if (format < NK_FORMAT_COLOR_BEGIN || format > NK_FORMAT_COLOR_END) return;
9487 
9488  val[0] = NK_SATURATE(vals[0]);
9489  val[1] = NK_SATURATE(vals[1]);
9490  val[2] = NK_SATURATE(vals[2]);
9491  val[3] = NK_SATURATE(vals[3]);
9492 
9493  switch (format) {
9494  default: NK_ASSERT(0 && "Invalid vertex layout color format"); break;
9495  case NK_FORMAT_R8G8B8A8:
9496  case NK_FORMAT_R8G8B8: {
9497  struct nk_color col = nk_rgba_fv(val);
9498  NK_MEMCPY(attr, &col.r, sizeof(col));
9499  } break;
9500  case NK_FORMAT_B8G8R8A8: {
9501  struct nk_color col = nk_rgba_fv(val);
9502  struct nk_color bgra = nk_rgba(col.b, col.g, col.r, col.a);
9503  NK_MEMCPY(attr, &bgra, sizeof(bgra));
9504  } break;
9505  case NK_FORMAT_R16G15B16: {
9506  nk_ushort col[3];
9507  col[0] = (nk_ushort)(val[0]*(float)NK_USHORT_MAX);
9508  col[1] = (nk_ushort)(val[1]*(float)NK_USHORT_MAX);
9509  col[2] = (nk_ushort)(val[2]*(float)NK_USHORT_MAX);
9510  NK_MEMCPY(attr, col, sizeof(col));
9511  } break;
9512  case NK_FORMAT_R16G15B16A16: {
9513  nk_ushort col[4];
9514  col[0] = (nk_ushort)(val[0]*(float)NK_USHORT_MAX);
9515  col[1] = (nk_ushort)(val[1]*(float)NK_USHORT_MAX);
9516  col[2] = (nk_ushort)(val[2]*(float)NK_USHORT_MAX);
9517  col[3] = (nk_ushort)(val[3]*(float)NK_USHORT_MAX);
9518  NK_MEMCPY(attr, col, sizeof(col));
9519  } break;
9520  case NK_FORMAT_R32G32B32: {
9521  nk_uint col[3];
9522  col[0] = (nk_uint)(val[0]*(float)NK_UINT_MAX);
9523  col[1] = (nk_uint)(val[1]*(float)NK_UINT_MAX);
9524  col[2] = (nk_uint)(val[2]*(float)NK_UINT_MAX);
9525  NK_MEMCPY(attr, col, sizeof(col));
9526  } break;
9527  case NK_FORMAT_R32G32B32A32: {
9528  nk_uint col[4];
9529  col[0] = (nk_uint)(val[0]*(float)NK_UINT_MAX);
9530  col[1] = (nk_uint)(val[1]*(float)NK_UINT_MAX);
9531  col[2] = (nk_uint)(val[2]*(float)NK_UINT_MAX);
9532  col[3] = (nk_uint)(val[3]*(float)NK_UINT_MAX);
9533  NK_MEMCPY(attr, col, sizeof(col));
9534  } break;
9535  case NK_FORMAT_R32G32B32A32_FLOAT:
9536  NK_MEMCPY(attr, val, sizeof(float)*4);
9537  break;
9538  case NK_FORMAT_R32G32B32A32_DOUBLE: {
9539  double col[4];
9540  col[0] = (double)val[0];
9541  col[1] = (double)val[1];
9542  col[2] = (double)val[2];
9543  col[3] = (double)val[3];
9544  NK_MEMCPY(attr, col, sizeof(col));
9545  } break;
9546  case NK_FORMAT_RGB32:
9547  case NK_FORMAT_RGBA32: {
9548  struct nk_color col = nk_rgba_fv(val);
9549  nk_uint color = nk_color_u32(col);
9550  NK_MEMCPY(attr, &color, sizeof(color));
9551  } break; }
9552 }
9553 NK_INTERN void
9554 nk_draw_vertex_element(void *dst, const float *values, int value_count,
9555  enum nk_draw_vertex_layout_format format)
9556 {
9557  int value_index;
9558  void *attribute = dst;
9559  /* if this triggers you tried to provide a color format for a value */
9560  NK_ASSERT(format < NK_FORMAT_COLOR_BEGIN);
9561  if (format >= NK_FORMAT_COLOR_BEGIN && format <= NK_FORMAT_COLOR_END) return;
9562  for (value_index = 0; value_index < value_count; ++value_index) {
9563  switch (format) {
9564  default: NK_ASSERT(0 && "invalid vertex layout format"); break;
9565  case NK_FORMAT_SCHAR: {
9566  char value = (char)NK_CLAMP((float)NK_SCHAR_MIN, values[value_index], (float)NK_SCHAR_MAX);
9567  NK_MEMCPY(attribute, &value, sizeof(value));
9568  attribute = (void*)((char*)attribute + sizeof(char));
9569  } break;
9570  case NK_FORMAT_SSHORT: {
9571  nk_short value = (nk_short)NK_CLAMP((float)NK_SSHORT_MIN, values[value_index], (float)NK_SSHORT_MAX);
9572  NK_MEMCPY(attribute, &value, sizeof(value));
9573  attribute = (void*)((char*)attribute + sizeof(value));
9574  } break;
9575  case NK_FORMAT_SINT: {
9576  nk_int value = (nk_int)NK_CLAMP((float)NK_SINT_MIN, values[value_index], (float)NK_SINT_MAX);
9577  NK_MEMCPY(attribute, &value, sizeof(value));
9578  attribute = (void*)((char*)attribute + sizeof(nk_int));
9579  } break;
9580  case NK_FORMAT_UCHAR: {
9581  unsigned char value = (unsigned char)NK_CLAMP((float)NK_UCHAR_MIN, values[value_index], (float)NK_UCHAR_MAX);
9582  NK_MEMCPY(attribute, &value, sizeof(value));
9583  attribute = (void*)((char*)attribute + sizeof(unsigned char));
9584  } break;
9585  case NK_FORMAT_USHORT: {
9586  nk_ushort value = (nk_ushort)NK_CLAMP((float)NK_USHORT_MIN, values[value_index], (float)NK_USHORT_MAX);
9587  NK_MEMCPY(attribute, &value, sizeof(value));
9588  attribute = (void*)((char*)attribute + sizeof(value));
9589  } break;
9590  case NK_FORMAT_UINT: {
9591  nk_uint value = (nk_uint)NK_CLAMP((float)NK_UINT_MIN, values[value_index], (float)NK_UINT_MAX);
9592  NK_MEMCPY(attribute, &value, sizeof(value));
9593  attribute = (void*)((char*)attribute + sizeof(nk_uint));
9594  } break;
9595  case NK_FORMAT_FLOAT:
9596  NK_MEMCPY(attribute, &values[value_index], sizeof(values[value_index]));
9597  attribute = (void*)((char*)attribute + sizeof(float));
9598  break;
9599  case NK_FORMAT_DOUBLE: {
9600  double value = (double)values[value_index];
9601  NK_MEMCPY(attribute, &value, sizeof(value));
9602  attribute = (void*)((char*)attribute + sizeof(double));
9603  } break;
9604  }
9605  }
9606 }
9607 NK_INTERN void*
9608 nk_draw_vertex(void *dst, const struct nk_convert_config *config,
9609  struct nk_vec2 pos, struct nk_vec2 uv, struct nk_colorf color)
9610 {
9611  void *result = (void*)((char*)dst + config->vertex_size);
9612  const struct nk_draw_vertex_layout_element *elem_iter = config->vertex_layout;
9613  while (!nk_draw_vertex_layout_element_is_end_of_layout(elem_iter)) {
9614  void *address = (void*)((char*)dst + elem_iter->offset);
9615  switch (elem_iter->attribute) {
9616  case NK_VERTEX_ATTRIBUTE_COUNT:
9617  default: NK_ASSERT(0 && "wrong element attribute"); break;
9618  case NK_VERTEX_POSITION: nk_draw_vertex_element(address, &pos.x, 2, elem_iter->format); break;
9619  case NK_VERTEX_TEXCOORD: nk_draw_vertex_element(address, &uv.x, 2, elem_iter->format); break;
9620  case NK_VERTEX_COLOR: nk_draw_vertex_color(address, &color.r, elem_iter->format); break;
9621  }
9622  elem_iter++;
9623  }
9624  return result;
9625 }
9626 NK_API void
9627 nk_draw_list_stroke_poly_line(struct nk_draw_list *list, const struct nk_vec2 *points,
9628  const unsigned int points_count, struct nk_color color, enum nk_draw_list_stroke closed,
9629  float thickness, enum nk_anti_aliasing aliasing)
9630 {
9631  nk_size count;
9632  int thick_line;
9633  struct nk_colorf col;
9634  struct nk_colorf col_trans;
9635  NK_ASSERT(list);
9636  if (!list || points_count < 2) return;
9637 
9638  color.a = (nk_byte)((float)color.a * list->config.global_alpha);
9639  count = points_count;
9640  if (!closed) count = points_count-1;
9641  thick_line = thickness > 1.0f;
9642 
9643 #ifdef NK_INCLUDE_COMMAND_USERDATA
9644  nk_draw_list_push_userdata(list, list->userdata);
9645 #endif
9646 
9647  color.a = (nk_byte)((float)color.a * list->config.global_alpha);
9648  nk_color_fv(&col.r, color);
9649  col_trans = col;
9650  col_trans.a = 0;
9651 
9652  if (aliasing == NK_ANTI_ALIASING_ON) {
9653  /* ANTI-ALIASED STROKE */
9654  const float AA_SIZE = 1.0f;
9655  NK_STORAGE const nk_size pnt_align = NK_ALIGNOF(struct nk_vec2);
9656  NK_STORAGE const nk_size pnt_size = sizeof(struct nk_vec2);
9657 
9658  /* allocate vertices and elements */
9659  nk_size i1 = 0;
9660  nk_size vertex_offset;
9661  nk_size index = list->vertex_count;
9662 
9663  const nk_size idx_count = (thick_line) ? (count * 18) : (count * 12);
9664  const nk_size vtx_count = (thick_line) ? (points_count * 4): (points_count *3);
9665 
9666  void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
9667  nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
9668 
9669  nk_size size;
9670  struct nk_vec2 *normals, *temp;
9671  if (!vtx || !ids) return;
9672 
9673  /* temporary allocate normals + points */
9674  vertex_offset = (nk_size)((nk_byte*)vtx - (nk_byte*)list->vertices->memory.ptr);
9675  nk_buffer_mark(list->vertices, NK_BUFFER_FRONT);
9676  size = pnt_size * ((thick_line) ? 5 : 3) * points_count;
9677  normals = (struct nk_vec2*) nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align);
9678  if (!normals) return;
9679  temp = normals + points_count;
9680 
9681  /* make sure vertex pointer is still correct */
9682  vtx = (void*)((nk_byte*)list->vertices->memory.ptr + vertex_offset);
9683 
9684  /* calculate normals */
9685  for (i1 = 0; i1 < count; ++i1) {
9686  const nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1);
9687  struct nk_vec2 diff = nk_vec2_sub(points[i2], points[i1]);
9688  float len;
9689 
9690  /* vec2 inverted length */
9691  len = nk_vec2_len_sqr(diff);
9692  if (len != 0.0f)
9693  len = nk_inv_sqrt(len);
9694  else len = 1.0f;
9695 
9696  diff = nk_vec2_muls(diff, len);
9697  normals[i1].x = diff.y;
9698  normals[i1].y = -diff.x;
9699  }
9700 
9701  if (!closed)
9702  normals[points_count-1] = normals[points_count-2];
9703 
9704  if (!thick_line) {
9705  nk_size idx1, i;
9706  if (!closed) {
9707  struct nk_vec2 d;
9708  temp[0] = nk_vec2_add(points[0], nk_vec2_muls(normals[0], AA_SIZE));
9709  temp[1] = nk_vec2_sub(points[0], nk_vec2_muls(normals[0], AA_SIZE));
9710  d = nk_vec2_muls(normals[points_count-1], AA_SIZE);
9711  temp[(points_count-1) * 2 + 0] = nk_vec2_add(points[points_count-1], d);
9712  temp[(points_count-1) * 2 + 1] = nk_vec2_sub(points[points_count-1], d);
9713  }
9714 
9715  /* fill elements */
9716  idx1 = index;
9717  for (i1 = 0; i1 < count; i1++) {
9718  struct nk_vec2 dm;
9719  float dmr2;
9720  nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1);
9721  nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 3);
9722 
9723  /* average normals */
9724  dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f);
9725  dmr2 = dm.x * dm.x + dm.y* dm.y;
9726  if (dmr2 > 0.000001f) {
9727  float scale = 1.0f/dmr2;
9728  scale = NK_MIN(100.0f, scale);
9729  dm = nk_vec2_muls(dm, scale);
9730  }
9731 
9732  dm = nk_vec2_muls(dm, AA_SIZE);
9733  temp[i2*2+0] = nk_vec2_add(points[i2], dm);
9734  temp[i2*2+1] = nk_vec2_sub(points[i2], dm);
9735 
9736  ids[0] = (nk_draw_index)(idx2 + 0); ids[1] = (nk_draw_index)(idx1+0);
9737  ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2);
9738  ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+0);
9739  ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1);
9740  ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0);
9741  ids[10]= (nk_draw_index)(idx2 + 0); ids[11]= (nk_draw_index)(idx2+1);
9742  ids += 12;
9743  idx1 = idx2;
9744  }
9745 
9746  /* fill vertices */
9747  for (i = 0; i < points_count; ++i) {
9748  const struct nk_vec2 uv = list->config.null.uv;
9749  vtx = nk_draw_vertex(vtx, &list->config, points[i], uv, col);
9750  vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+0], uv, col_trans);
9751  vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+1], uv, col_trans);
9752  }
9753  } else {
9754  nk_size idx1, i;
9755  const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f;
9756  if (!closed) {
9757  struct nk_vec2 d1 = nk_vec2_muls(normals[0], half_inner_thickness + AA_SIZE);
9758  struct nk_vec2 d2 = nk_vec2_muls(normals[0], half_inner_thickness);
9759 
9760  temp[0] = nk_vec2_add(points[0], d1);
9761  temp[1] = nk_vec2_add(points[0], d2);
9762  temp[2] = nk_vec2_sub(points[0], d2);
9763  temp[3] = nk_vec2_sub(points[0], d1);
9764 
9765  d1 = nk_vec2_muls(normals[points_count-1], half_inner_thickness + AA_SIZE);
9766  d2 = nk_vec2_muls(normals[points_count-1], half_inner_thickness);
9767 
9768  temp[(points_count-1)*4+0] = nk_vec2_add(points[points_count-1], d1);
9769  temp[(points_count-1)*4+1] = nk_vec2_add(points[points_count-1], d2);
9770  temp[(points_count-1)*4+2] = nk_vec2_sub(points[points_count-1], d2);
9771  temp[(points_count-1)*4+3] = nk_vec2_sub(points[points_count-1], d1);
9772  }
9773 
9774  /* add all elements */
9775  idx1 = index;
9776  for (i1 = 0; i1 < count; ++i1) {
9777  struct nk_vec2 dm_out, dm_in;
9778  const nk_size i2 = ((i1+1) == points_count) ? 0: (i1 + 1);
9779  nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 4);
9780 
9781  /* average normals */
9782  struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f);
9783  float dmr2 = dm.x * dm.x + dm.y* dm.y;
9784  if (dmr2 > 0.000001f) {
9785  float scale = 1.0f/dmr2;
9786  scale = NK_MIN(100.0f, scale);
9787  dm = nk_vec2_muls(dm, scale);
9788  }
9789 
9790  dm_out = nk_vec2_muls(dm, ((half_inner_thickness) + AA_SIZE));
9791  dm_in = nk_vec2_muls(dm, half_inner_thickness);
9792  temp[i2*4+0] = nk_vec2_add(points[i2], dm_out);
9793  temp[i2*4+1] = nk_vec2_add(points[i2], dm_in);
9794  temp[i2*4+2] = nk_vec2_sub(points[i2], dm_in);
9795  temp[i2*4+3] = nk_vec2_sub(points[i2], dm_out);
9796 
9797  /* add indexes */
9798  ids[0] = (nk_draw_index)(idx2 + 1); ids[1] = (nk_draw_index)(idx1+1);
9799  ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2);
9800  ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+1);
9801  ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1);
9802  ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0);
9803  ids[10]= (nk_draw_index)(idx2 + 0); ids[11] = (nk_draw_index)(idx2+1);
9804  ids[12]= (nk_draw_index)(idx2 + 2); ids[13] = (nk_draw_index)(idx1+2);
9805  ids[14]= (nk_draw_index)(idx1 + 3); ids[15] = (nk_draw_index)(idx1+3);
9806  ids[16]= (nk_draw_index)(idx2 + 3); ids[17] = (nk_draw_index)(idx2+2);
9807  ids += 18;
9808  idx1 = idx2;
9809  }
9810 
9811  /* add vertices */
9812  for (i = 0; i < points_count; ++i) {
9813  const struct nk_vec2 uv = list->config.null.uv;
9814  vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+0], uv, col_trans);
9815  vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+1], uv, col);
9816  vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+2], uv, col);
9817  vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+3], uv, col_trans);
9818  }
9819  }
9820  /* free temporary normals + points */
9821  nk_buffer_reset(list->vertices, NK_BUFFER_FRONT);
9822  } else {
9823  /* NON ANTI-ALIASED STROKE */
9824  nk_size i1 = 0;
9825  nk_size idx = list->vertex_count;
9826  const nk_size idx_count = count * 6;
9827  const nk_size vtx_count = count * 4;
9828  void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
9829  nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
9830  if (!vtx || !ids) return;
9831 
9832  for (i1 = 0; i1 < count; ++i1) {
9833  float dx, dy;
9834  const struct nk_vec2 uv = list->config.null.uv;
9835  const nk_size i2 = ((i1+1) == points_count) ? 0 : i1 + 1;
9836  const struct nk_vec2 p1 = points[i1];
9837  const struct nk_vec2 p2 = points[i2];
9838  struct nk_vec2 diff = nk_vec2_sub(p2, p1);
9839  float len;
9840 
9841  /* vec2 inverted length */
9842  len = nk_vec2_len_sqr(diff);
9843  if (len != 0.0f)
9844  len = nk_inv_sqrt(len);
9845  else len = 1.0f;
9846  diff = nk_vec2_muls(diff, len);
9847 
9848  /* add vertices */
9849  dx = diff.x * (thickness * 0.5f);
9850  dy = diff.y * (thickness * 0.5f);
9851 
9852  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p1.x + dy, p1.y - dx), uv, col);
9853  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p2.x + dy, p2.y - dx), uv, col);
9854  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p2.x - dy, p2.y + dx), uv, col);
9855  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p1.x - dy, p1.y + dx), uv, col);
9856 
9857  ids[0] = (nk_draw_index)(idx+0); ids[1] = (nk_draw_index)(idx+1);
9858  ids[2] = (nk_draw_index)(idx+2); ids[3] = (nk_draw_index)(idx+0);
9859  ids[4] = (nk_draw_index)(idx+2); ids[5] = (nk_draw_index)(idx+3);
9860 
9861  ids += 6;
9862  idx += 4;
9863  }
9864  }
9865 }
9866 NK_API void
9867 nk_draw_list_fill_poly_convex(struct nk_draw_list *list,
9868  const struct nk_vec2 *points, const unsigned int points_count,
9869  struct nk_color color, enum nk_anti_aliasing aliasing)
9870 {
9871  struct nk_colorf col;
9872  struct nk_colorf col_trans;
9873 
9874  NK_STORAGE const nk_size pnt_align = NK_ALIGNOF(struct nk_vec2);
9875  NK_STORAGE const nk_size pnt_size = sizeof(struct nk_vec2);
9876  NK_ASSERT(list);
9877  if (!list || points_count < 3) return;
9878 
9879 #ifdef NK_INCLUDE_COMMAND_USERDATA
9880  nk_draw_list_push_userdata(list, list->userdata);
9881 #endif
9882 
9883  color.a = (nk_byte)((float)color.a * list->config.global_alpha);
9884  nk_color_fv(&col.r, color);
9885  col_trans = col;
9886  col_trans.a = 0;
9887 
9888  if (aliasing == NK_ANTI_ALIASING_ON) {
9889  nk_size i = 0;
9890  nk_size i0 = 0;
9891  nk_size i1 = 0;
9892 
9893  const float AA_SIZE = 1.0f;
9894  nk_size vertex_offset = 0;
9895  nk_size index = list->vertex_count;
9896 
9897  const nk_size idx_count = (points_count-2)*3 + points_count*6;
9898  const nk_size vtx_count = (points_count*2);
9899 
9900  void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
9901  nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
9902 
9903  nk_size size = 0;
9904  struct nk_vec2 *normals = 0;
9905  unsigned int vtx_inner_idx = (unsigned int)(index + 0);
9906  unsigned int vtx_outer_idx = (unsigned int)(index + 1);
9907  if (!vtx || !ids) return;
9908 
9909  /* temporary allocate normals */
9910  vertex_offset = (nk_size)((nk_byte*)vtx - (nk_byte*)list->vertices->memory.ptr);
9911  nk_buffer_mark(list->vertices, NK_BUFFER_FRONT);
9912  size = pnt_size * points_count;
9913  normals = (struct nk_vec2*) nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align);
9914  if (!normals) return;
9915  vtx = (void*)((nk_byte*)list->vertices->memory.ptr + vertex_offset);
9916 
9917  /* add elements */
9918  for (i = 2; i < points_count; i++) {
9919  ids[0] = (nk_draw_index)(vtx_inner_idx);
9920  ids[1] = (nk_draw_index)(vtx_inner_idx + ((i-1) << 1));
9921  ids[2] = (nk_draw_index)(vtx_inner_idx + (i << 1));
9922  ids += 3;
9923  }
9924 
9925  /* compute normals */
9926  for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
9927  struct nk_vec2 p0 = points[i0];
9928  struct nk_vec2 p1 = points[i1];
9929  struct nk_vec2 diff = nk_vec2_sub(p1, p0);
9930 
9931  /* vec2 inverted length */
9932  float len = nk_vec2_len_sqr(diff);
9933  if (len != 0.0f)
9934  len = nk_inv_sqrt(len);
9935  else len = 1.0f;
9936  diff = nk_vec2_muls(diff, len);
9937 
9938  normals[i0].x = diff.y;
9939  normals[i0].y = -diff.x;
9940  }
9941 
9942  /* add vertices + indexes */
9943  for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
9944  const struct nk_vec2 uv = list->config.null.uv;
9945  struct nk_vec2 n0 = normals[i0];
9946  struct nk_vec2 n1 = normals[i1];
9947  struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(n0, n1), 0.5f);
9948  float dmr2 = dm.x*dm.x + dm.y*dm.y;
9949  if (dmr2 > 0.000001f) {
9950  float scale = 1.0f / dmr2;
9951  scale = NK_MIN(scale, 100.0f);
9952  dm = nk_vec2_muls(dm, scale);
9953  }
9954  dm = nk_vec2_muls(dm, AA_SIZE * 0.5f);
9955 
9956  /* add vertices */
9957  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_sub(points[i1], dm), uv, col);
9958  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_add(points[i1], dm), uv, col_trans);
9959 
9960  /* add indexes */
9961  ids[0] = (nk_draw_index)(vtx_inner_idx+(i1<<1));
9962  ids[1] = (nk_draw_index)(vtx_inner_idx+(i0<<1));
9963  ids[2] = (nk_draw_index)(vtx_outer_idx+(i0<<1));
9964  ids[3] = (nk_draw_index)(vtx_outer_idx+(i0<<1));
9965  ids[4] = (nk_draw_index)(vtx_outer_idx+(i1<<1));
9966  ids[5] = (nk_draw_index)(vtx_inner_idx+(i1<<1));
9967  ids += 6;
9968  }
9969  /* free temporary normals + points */
9970  nk_buffer_reset(list->vertices, NK_BUFFER_FRONT);
9971  } else {
9972  nk_size i = 0;
9973  nk_size index = list->vertex_count;
9974  const nk_size idx_count = (points_count-2)*3;
9975  const nk_size vtx_count = points_count;
9976  void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
9977  nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
9978 
9979  if (!vtx || !ids) return;
9980  for (i = 0; i < vtx_count; ++i)
9981  vtx = nk_draw_vertex(vtx, &list->config, points[i], list->config.null.uv, col);
9982  for (i = 2; i < points_count; ++i) {
9983  ids[0] = (nk_draw_index)index;
9984  ids[1] = (nk_draw_index)(index+ i - 1);
9985  ids[2] = (nk_draw_index)(index+i);
9986  ids += 3;
9987  }
9988  }
9989 }
9990 NK_API void
9991 nk_draw_list_path_clear(struct nk_draw_list *list)
9992 {
9993  NK_ASSERT(list);
9994  if (!list) return;
9995  nk_buffer_reset(list->buffer, NK_BUFFER_FRONT);
9996  list->path_count = 0;
9997  list->path_offset = 0;
9998 }
9999 NK_API void
10000 nk_draw_list_path_line_to(struct nk_draw_list *list, struct nk_vec2 pos)
10001 {
10002  struct nk_vec2 *points = 0;
10003  struct nk_draw_command *cmd = 0;
10004  NK_ASSERT(list);
10005  if (!list) return;
10006  if (!list->cmd_count)
10007  nk_draw_list_add_clip(list, nk_null_rect);
10008 
10009  cmd = nk_draw_list_command_last(list);
10010  if (cmd && cmd->texture.ptr != list->config.null.texture.ptr)
10011  nk_draw_list_push_image(list, list->config.null.texture);
10012 
10013  points = nk_draw_list_alloc_path(list, 1);
10014  if (!points) return;
10015  points[0] = pos;
10016 }
10017 NK_API void
10018 nk_draw_list_path_arc_to_fast(struct nk_draw_list *list, struct nk_vec2 center,
10019  float radius, int a_min, int a_max)
10020 {
10021  int a = 0;
10022  NK_ASSERT(list);
10023  if (!list) return;
10024  if (a_min <= a_max) {
10025  for (a = a_min; a <= a_max; a++) {
10026  const struct nk_vec2 c = list->circle_vtx[(nk_size)a % NK_LEN(list->circle_vtx)];
10027  const float x = center.x + c.x * radius;
10028  const float y = center.y + c.y * radius;
10029  nk_draw_list_path_line_to(list, nk_vec2(x, y));
10030  }
10031  }
10032 }
10033 NK_API void
10034 nk_draw_list_path_arc_to(struct nk_draw_list *list, struct nk_vec2 center,
10035  float radius, float a_min, float a_max, unsigned int segments)
10036 {
10037  unsigned int i = 0;
10038  NK_ASSERT(list);
10039  if (!list) return;
10040  if (radius == 0.0f) return;
10041 
10042  /* This algorithm for arc drawing relies on these two trigonometric identities[1]:
10043  sin(a + b) = sin(a) * cos(b) + cos(a) * sin(b)
10044  cos(a + b) = cos(a) * cos(b) - sin(a) * sin(b)
10045 
10046  Two coordinates (x, y) of a point on a circle centered on
10047  the origin can be written in polar form as:
10048  x = r * cos(a)
10049  y = r * sin(a)
10050  where r is the radius of the circle,
10051  a is the angle between (x, y) and the origin.
10052 
10053  This allows us to rotate the coordinates around the
10054  origin by an angle b using the following transformation:
10055  x' = r * cos(a + b) = x * cos(b) - y * sin(b)
10056  y' = r * sin(a + b) = y * cos(b) + x * sin(b)
10057 
10058  [1] https://en.wikipedia.org/wiki/List_of_trigonometric_identities#Angle_sum_and_difference_identities
10059  */
10060  {const float d_angle = (a_max - a_min) / (float)segments;
10061  const float sin_d = (float)NK_SIN(d_angle);
10062  const float cos_d = (float)NK_COS(d_angle);
10063 
10064  float cx = (float)NK_COS(a_min) * radius;
10065  float cy = (float)NK_SIN(a_min) * radius;
10066  for(i = 0; i <= segments; ++i) {
10067  float new_cx, new_cy;
10068  const float x = center.x + cx;
10069  const float y = center.y + cy;
10070  nk_draw_list_path_line_to(list, nk_vec2(x, y));
10071 
10072  new_cx = cx * cos_d - cy * sin_d;
10073  new_cy = cy * cos_d + cx * sin_d;
10074  cx = new_cx;
10075  cy = new_cy;
10076  }}
10077 }
10078 NK_API void
10079 nk_draw_list_path_rect_to(struct nk_draw_list *list, struct nk_vec2 a,
10080  struct nk_vec2 b, float rounding)
10081 {
10082  float r;
10083  NK_ASSERT(list);
10084  if (!list) return;
10085  r = rounding;
10086  r = NK_MIN(r, ((b.x-a.x) < 0) ? -(b.x-a.x): (b.x-a.x));
10087  r = NK_MIN(r, ((b.y-a.y) < 0) ? -(b.y-a.y): (b.y-a.y));
10088 
10089  if (r == 0.0f) {
10090  nk_draw_list_path_line_to(list, a);
10091  nk_draw_list_path_line_to(list, nk_vec2(b.x,a.y));
10092  nk_draw_list_path_line_to(list, b);
10093  nk_draw_list_path_line_to(list, nk_vec2(a.x,b.y));
10094  } else {
10095  nk_draw_list_path_arc_to_fast(list, nk_vec2(a.x + r, a.y + r), r, 6, 9);
10096  nk_draw_list_path_arc_to_fast(list, nk_vec2(b.x - r, a.y + r), r, 9, 12);
10097  nk_draw_list_path_arc_to_fast(list, nk_vec2(b.x - r, b.y - r), r, 0, 3);
10098  nk_draw_list_path_arc_to_fast(list, nk_vec2(a.x + r, b.y - r), r, 3, 6);
10099  }
10100 }
10101 NK_API void
10102 nk_draw_list_path_curve_to(struct nk_draw_list *list, struct nk_vec2 p2,
10103  struct nk_vec2 p3, struct nk_vec2 p4, unsigned int num_segments)
10104 {
10105  float t_step;
10106  unsigned int i_step;
10107  struct nk_vec2 p1;
10108 
10109  NK_ASSERT(list);
10110  NK_ASSERT(list->path_count);
10111  if (!list || !list->path_count) return;
10112  num_segments = NK_MAX(num_segments, 1);
10113 
10114  p1 = nk_draw_list_path_last(list);
10115  t_step = 1.0f/(float)num_segments;
10116  for (i_step = 1; i_step <= num_segments; ++i_step) {
10117  float t = t_step * (float)i_step;
10118  float u = 1.0f - t;
10119  float w1 = u*u*u;
10120  float w2 = 3*u*u*t;
10121  float w3 = 3*u*t*t;
10122  float w4 = t * t *t;
10123  float x = w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x;
10124  float y = w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y;
10125  nk_draw_list_path_line_to(list, nk_vec2(x,y));
10126  }
10127 }
10128 NK_API void
10129 nk_draw_list_path_fill(struct nk_draw_list *list, struct nk_color color)
10130 {
10131  struct nk_vec2 *points;
10132  NK_ASSERT(list);
10133  if (!list) return;
10134  points = (struct nk_vec2*)nk_buffer_memory(list->buffer);
10135  nk_draw_list_fill_poly_convex(list, points, list->path_count, color, list->config.shape_AA);
10136  nk_draw_list_path_clear(list);
10137 }
10138 NK_API void
10139 nk_draw_list_path_stroke(struct nk_draw_list *list, struct nk_color color,
10140  enum nk_draw_list_stroke closed, float thickness)
10141 {
10142  struct nk_vec2 *points;
10143  NK_ASSERT(list);
10144  if (!list) return;
10145  points = (struct nk_vec2*)nk_buffer_memory(list->buffer);
10146  nk_draw_list_stroke_poly_line(list, points, list->path_count, color,
10147  closed, thickness, list->config.line_AA);
10148  nk_draw_list_path_clear(list);
10149 }
10150 NK_API void
10151 nk_draw_list_stroke_line(struct nk_draw_list *list, struct nk_vec2 a,
10152  struct nk_vec2 b, struct nk_color col, float thickness)
10153 {
10154  NK_ASSERT(list);
10155  if (!list || !col.a) return;
10156  if (list->line_AA == NK_ANTI_ALIASING_ON) {
10157  nk_draw_list_path_line_to(list, a);
10158  nk_draw_list_path_line_to(list, b);
10159  } else {
10160  nk_draw_list_path_line_to(list, nk_vec2_sub(a,nk_vec2(0.5f,0.5f)));
10161  nk_draw_list_path_line_to(list, nk_vec2_sub(b,nk_vec2(0.5f,0.5f)));
10162  }
10163  nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness);
10164 }
10165 NK_API void
10166 nk_draw_list_fill_rect(struct nk_draw_list *list, struct nk_rect rect,
10167  struct nk_color col, float rounding)
10168 {
10169  NK_ASSERT(list);
10170  if (!list || !col.a) return;
10171 
10172  if (list->line_AA == NK_ANTI_ALIASING_ON) {
10173  nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y),
10174  nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
10175  } else {
10176  nk_draw_list_path_rect_to(list, nk_vec2(rect.x-0.5f, rect.y-0.5f),
10177  nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
10178  } nk_draw_list_path_fill(list, col);
10179 }
10180 NK_API void
10181 nk_draw_list_stroke_rect(struct nk_draw_list *list, struct nk_rect rect,
10182  struct nk_color col, float rounding, float thickness)
10183 {
10184  NK_ASSERT(list);
10185  if (!list || !col.a) return;
10186  if (list->line_AA == NK_ANTI_ALIASING_ON) {
10187  nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y),
10188  nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
10189  } else {
10190  nk_draw_list_path_rect_to(list, nk_vec2(rect.x-0.5f, rect.y-0.5f),
10191  nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
10192  } nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
10193 }
10194 NK_API void
10195 nk_draw_list_fill_rect_multi_color(struct nk_draw_list *list, struct nk_rect rect,
10196  struct nk_color left, struct nk_color top, struct nk_color right,
10197  struct nk_color bottom)
10198 {
10199  void *vtx;
10200  struct nk_colorf col_left, col_top;
10201  struct nk_colorf col_right, col_bottom;
10202  nk_draw_index *idx;
10203  nk_draw_index index;
10204 
10205  nk_color_fv(&col_left.r, left);
10206  nk_color_fv(&col_right.r, right);
10207  nk_color_fv(&col_top.r, top);
10208  nk_color_fv(&col_bottom.r, bottom);
10209 
10210  NK_ASSERT(list);
10211  if (!list) return;
10212 
10213  nk_draw_list_push_image(list, list->config.null.texture);
10214  index = (nk_draw_index)list->vertex_count;
10215  vtx = nk_draw_list_alloc_vertices(list, 4);
10216  idx = nk_draw_list_alloc_elements(list, 6);
10217  if (!vtx || !idx) return;
10218 
10219  idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1);
10220  idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
10221  idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
10222 
10223  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y), list->config.null.uv, col_left);
10224  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y), list->config.null.uv, col_top);
10225  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y + rect.h), list->config.null.uv, col_right);
10226  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y + rect.h), list->config.null.uv, col_bottom);
10227 }
10228 NK_API void
10229 nk_draw_list_fill_triangle(struct nk_draw_list *list, struct nk_vec2 a,
10230  struct nk_vec2 b, struct nk_vec2 c, struct nk_color col)
10231 {
10232  NK_ASSERT(list);
10233  if (!list || !col.a) return;
10234  nk_draw_list_path_line_to(list, a);
10235  nk_draw_list_path_line_to(list, b);
10236  nk_draw_list_path_line_to(list, c);
10237  nk_draw_list_path_fill(list, col);
10238 }
10239 NK_API void
10240 nk_draw_list_stroke_triangle(struct nk_draw_list *list, struct nk_vec2 a,
10241  struct nk_vec2 b, struct nk_vec2 c, struct nk_color col, float thickness)
10242 {
10243  NK_ASSERT(list);
10244  if (!list || !col.a) return;
10245  nk_draw_list_path_line_to(list, a);
10246  nk_draw_list_path_line_to(list, b);
10247  nk_draw_list_path_line_to(list, c);
10248  nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
10249 }
10250 NK_API void
10251 nk_draw_list_fill_circle(struct nk_draw_list *list, struct nk_vec2 center,
10252  float radius, struct nk_color col, unsigned int segs)
10253 {
10254  float a_max;
10255  NK_ASSERT(list);
10256  if (!list || !col.a) return;
10257  a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs;
10258  nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs);
10259  nk_draw_list_path_fill(list, col);
10260 }
10261 NK_API void
10262 nk_draw_list_stroke_circle(struct nk_draw_list *list, struct nk_vec2 center,
10263  float radius, struct nk_color col, unsigned int segs, float thickness)
10264 {
10265  float a_max;
10266  NK_ASSERT(list);
10267  if (!list || !col.a) return;
10268  a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs;
10269  nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs);
10270  nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
10271 }
10272 NK_API void
10273 nk_draw_list_stroke_curve(struct nk_draw_list *list, struct nk_vec2 p0,
10274  struct nk_vec2 cp0, struct nk_vec2 cp1, struct nk_vec2 p1,
10275  struct nk_color col, unsigned int segments, float thickness)
10276 {
10277  NK_ASSERT(list);
10278  if (!list || !col.a) return;
10279  nk_draw_list_path_line_to(list, p0);
10280  nk_draw_list_path_curve_to(list, cp0, cp1, p1, segments);
10281  nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness);
10282 }
10283 NK_INTERN void
10284 nk_draw_list_push_rect_uv(struct nk_draw_list *list, struct nk_vec2 a,
10285  struct nk_vec2 c, struct nk_vec2 uva, struct nk_vec2 uvc,
10286  struct nk_color color)
10287 {
10288  void *vtx;
10289  struct nk_vec2 uvb;
10290  struct nk_vec2 uvd;
10291  struct nk_vec2 b;
10292  struct nk_vec2 d;
10293 
10294  struct nk_colorf col;
10295  nk_draw_index *idx;
10296  nk_draw_index index;
10297  NK_ASSERT(list);
10298  if (!list) return;
10299 
10300  nk_color_fv(&col.r, color);
10301  uvb = nk_vec2(uvc.x, uva.y);
10302  uvd = nk_vec2(uva.x, uvc.y);
10303  b = nk_vec2(c.x, a.y);
10304  d = nk_vec2(a.x, c.y);
10305 
10306  index = (nk_draw_index)list->vertex_count;
10307  vtx = nk_draw_list_alloc_vertices(list, 4);
10308  idx = nk_draw_list_alloc_elements(list, 6);
10309  if (!vtx || !idx) return;
10310 
10311  idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1);
10312  idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
10313  idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
10314 
10315  vtx = nk_draw_vertex(vtx, &list->config, a, uva, col);
10316  vtx = nk_draw_vertex(vtx, &list->config, b, uvb, col);
10317  vtx = nk_draw_vertex(vtx, &list->config, c, uvc, col);
10318  vtx = nk_draw_vertex(vtx, &list->config, d, uvd, col);
10319 }
10320 NK_API void
10321 nk_draw_list_add_image(struct nk_draw_list *list, struct nk_image texture,
10322  struct nk_rect rect, struct nk_color color)
10323 {
10324  NK_ASSERT(list);
10325  if (!list) return;
10326  /* push new command with given texture */
10327  nk_draw_list_push_image(list, texture.handle);
10328  if (nk_image_is_subimage(&texture)) {
10329  /* add region inside of the texture */
10330  struct nk_vec2 uv[2];
10331  uv[0].x = (float)texture.region[0]/(float)texture.w;
10332  uv[0].y = (float)texture.region[1]/(float)texture.h;
10333  uv[1].x = (float)(texture.region[0] + texture.region[2])/(float)texture.w;
10334  uv[1].y = (float)(texture.region[1] + texture.region[3])/(float)texture.h;
10335  nk_draw_list_push_rect_uv(list, nk_vec2(rect.x, rect.y),
10336  nk_vec2(rect.x + rect.w, rect.y + rect.h), uv[0], uv[1], color);
10337  } else nk_draw_list_push_rect_uv(list, nk_vec2(rect.x, rect.y),
10338  nk_vec2(rect.x + rect.w, rect.y + rect.h),
10339  nk_vec2(0.0f, 0.0f), nk_vec2(1.0f, 1.0f),color);
10340 }
10341 NK_API void
10342 nk_draw_list_add_text(struct nk_draw_list *list, const struct nk_user_font *font,
10343  struct nk_rect rect, const char *text, int len, float font_height,
10344  struct nk_color fg)
10345 {
10346  float x = 0;
10347  int text_len = 0;
10348  nk_rune unicode = 0;
10349  nk_rune next = 0;
10350  int glyph_len = 0;
10351  int next_glyph_len = 0;
10352  struct nk_user_font_glyph g;
10353 
10354  NK_ASSERT(list);
10355  if (!list || !len || !text) return;
10356  if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
10357  list->clip_rect.x, list->clip_rect.y, list->clip_rect.w, list->clip_rect.h)) return;
10358 
10359  nk_draw_list_push_image(list, font->texture);
10360  x = rect.x;
10361  glyph_len = nk_utf_decode(text, &unicode, len);
10362  if (!glyph_len) return;
10363 
10364  /* draw every glyph image */
10365  fg.a = (nk_byte)((float)fg.a * list->config.global_alpha);
10366  while (text_len < len && glyph_len) {
10367  float gx, gy, gh, gw;
10368  float char_width = 0;
10369  if (unicode == NK_UTF_INVALID) break;
10370 
10371  /* query currently drawn glyph information */
10372  next_glyph_len = nk_utf_decode(text + text_len + glyph_len, &next, (int)len - text_len);
10373  font->query(font->userdata, font_height, &g, unicode,
10374  (next == NK_UTF_INVALID) ? '\0' : next);
10375 
10376  /* calculate and draw glyph drawing rectangle and image */
10377  gx = x + g.offset.x;
10378  gy = rect.y + g.offset.y;
10379  gw = g.width; gh = g.height;
10380  char_width = g.xadvance;
10381  nk_draw_list_push_rect_uv(list, nk_vec2(gx,gy), nk_vec2(gx + gw, gy+ gh),
10382  g.uv[0], g.uv[1], fg);
10383 
10384  /* offset next glyph */
10385  text_len += glyph_len;
10386  x += char_width;
10387  glyph_len = next_glyph_len;
10388  unicode = next;
10389  }
10390 }
10392 nk_convert(struct nk_context *ctx, struct nk_buffer *cmds,
10393  struct nk_buffer *vertices, struct nk_buffer *elements,
10394  const struct nk_convert_config *config)
10395 {
10397  const struct nk_command *cmd;
10398  NK_ASSERT(ctx);
10399  NK_ASSERT(cmds);
10400  NK_ASSERT(vertices);
10401  NK_ASSERT(elements);
10402  NK_ASSERT(config);
10403  NK_ASSERT(config->vertex_layout);
10404  NK_ASSERT(config->vertex_size);
10405  if (!ctx || !cmds || !vertices || !elements || !config || !config->vertex_layout)
10406  return NK_CONVERT_INVALID_PARAM;
10407 
10408  nk_draw_list_setup(&ctx->draw_list, config, cmds, vertices, elements,
10409  config->line_AA, config->shape_AA);
10410  nk_foreach(cmd, ctx)
10411  {
10412 #ifdef NK_INCLUDE_COMMAND_USERDATA
10413  ctx->draw_list.userdata = cmd->userdata;
10414 #endif
10415  switch (cmd->type) {
10416  case NK_COMMAND_NOP: break;
10417  case NK_COMMAND_SCISSOR: {
10418  const struct nk_command_scissor *s = (const struct nk_command_scissor*)cmd;
10419  nk_draw_list_add_clip(&ctx->draw_list, nk_rect(s->x, s->y, s->w, s->h));
10420  } break;
10421  case NK_COMMAND_LINE: {
10422  const struct nk_command_line *l = (const struct nk_command_line*)cmd;
10423  nk_draw_list_stroke_line(&ctx->draw_list, nk_vec2(l->begin.x, l->begin.y),
10424  nk_vec2(l->end.x, l->end.y), l->color, l->line_thickness);
10425  } break;
10426  case NK_COMMAND_CURVE: {
10427  const struct nk_command_curve *q = (const struct nk_command_curve*)cmd;
10428  nk_draw_list_stroke_curve(&ctx->draw_list, nk_vec2(q->begin.x, q->begin.y),
10429  nk_vec2(q->ctrl[0].x, q->ctrl[0].y), nk_vec2(q->ctrl[1].x,
10430  q->ctrl[1].y), nk_vec2(q->end.x, q->end.y), q->color,
10431  config->curve_segment_count, q->line_thickness);
10432  } break;
10433  case NK_COMMAND_RECT: {
10434  const struct nk_command_rect *r = (const struct nk_command_rect*)cmd;
10435  nk_draw_list_stroke_rect(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h),
10436  r->color, (float)r->rounding, r->line_thickness);
10437  } break;
10438  case NK_COMMAND_RECT_FILLED: {
10439  const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled*)cmd;
10440  nk_draw_list_fill_rect(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h),
10441  r->color, (float)r->rounding);
10442  } break;
10444  const struct nk_command_rect_multi_color *r = (const struct nk_command_rect_multi_color*)cmd;
10445  nk_draw_list_fill_rect_multi_color(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h),
10446  r->left, r->top, r->right, r->bottom);
10447  } break;
10448  case NK_COMMAND_CIRCLE: {
10449  const struct nk_command_circle *c = (const struct nk_command_circle*)cmd;
10450  nk_draw_list_stroke_circle(&ctx->draw_list, nk_vec2((float)c->x + (float)c->w/2,
10451  (float)c->y + (float)c->h/2), (float)c->w/2, c->color,
10452  config->circle_segment_count, c->line_thickness);
10453  } break;
10454  case NK_COMMAND_CIRCLE_FILLED: {
10455  const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
10456  nk_draw_list_fill_circle(&ctx->draw_list, nk_vec2((float)c->x + (float)c->w/2,
10457  (float)c->y + (float)c->h/2), (float)c->w/2, c->color,
10458  config->circle_segment_count);
10459  } break;
10460  case NK_COMMAND_ARC: {
10461  const struct nk_command_arc *c = (const struct nk_command_arc*)cmd;
10462  nk_draw_list_path_line_to(&ctx->draw_list, nk_vec2(c->cx, c->cy));
10463  nk_draw_list_path_arc_to(&ctx->draw_list, nk_vec2(c->cx, c->cy), c->r,
10464  c->a[0], c->a[1], config->arc_segment_count);
10465  nk_draw_list_path_stroke(&ctx->draw_list, c->color, NK_STROKE_CLOSED, c->line_thickness);
10466  } break;
10467  case NK_COMMAND_ARC_FILLED: {
10468  const struct nk_command_arc_filled *c = (const struct nk_command_arc_filled*)cmd;
10469  nk_draw_list_path_line_to(&ctx->draw_list, nk_vec2(c->cx, c->cy));
10470  nk_draw_list_path_arc_to(&ctx->draw_list, nk_vec2(c->cx, c->cy), c->r,
10471  c->a[0], c->a[1], config->arc_segment_count);
10472  nk_draw_list_path_fill(&ctx->draw_list, c->color);
10473  } break;
10474  case NK_COMMAND_TRIANGLE: {
10475  const struct nk_command_triangle *t = (const struct nk_command_triangle*)cmd;
10476  nk_draw_list_stroke_triangle(&ctx->draw_list, nk_vec2(t->a.x, t->a.y),
10477  nk_vec2(t->b.x, t->b.y), nk_vec2(t->c.x, t->c.y), t->color,
10478  t->line_thickness);
10479  } break;
10481  const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled*)cmd;
10482  nk_draw_list_fill_triangle(&ctx->draw_list, nk_vec2(t->a.x, t->a.y),
10483  nk_vec2(t->b.x, t->b.y), nk_vec2(t->c.x, t->c.y), t->color);
10484  } break;
10485  case NK_COMMAND_POLYGON: {
10486  int i;
10487  const struct nk_command_polygon*p = (const struct nk_command_polygon*)cmd;
10488  for (i = 0; i < p->point_count; ++i) {
10489  struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y);
10490  nk_draw_list_path_line_to(&ctx->draw_list, pnt);
10491  }
10492  nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_CLOSED, p->line_thickness);
10493  } break;
10495  int i;
10496  const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled*)cmd;
10497  for (i = 0; i < p->point_count; ++i) {
10498  struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y);
10499  nk_draw_list_path_line_to(&ctx->draw_list, pnt);
10500  }
10501  nk_draw_list_path_fill(&ctx->draw_list, p->color);
10502  } break;
10503  case NK_COMMAND_POLYLINE: {
10504  int i;
10505  const struct nk_command_polyline *p = (const struct nk_command_polyline*)cmd;
10506  for (i = 0; i < p->point_count; ++i) {
10507  struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y);
10508  nk_draw_list_path_line_to(&ctx->draw_list, pnt);
10509  }
10510  nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_OPEN, p->line_thickness);
10511  } break;
10512  case NK_COMMAND_TEXT: {
10513  const struct nk_command_text *t = (const struct nk_command_text*)cmd;
10514  nk_draw_list_add_text(&ctx->draw_list, t->font, nk_rect(t->x, t->y, t->w, t->h),
10515  t->string, t->length, t->height, t->foreground);
10516  } break;
10517  case NK_COMMAND_IMAGE: {
10518  const struct nk_command_image *i = (const struct nk_command_image*)cmd;
10519  nk_draw_list_add_image(&ctx->draw_list, i->img, nk_rect(i->x, i->y, i->w, i->h), i->col);
10520  } break;
10521  case NK_COMMAND_CUSTOM: {
10522  const struct nk_command_custom *c = (const struct nk_command_custom*)cmd;
10523  c->callback(&ctx->draw_list, c->x, c->y, c->w, c->h, c->callback_data);
10524  } break;
10525  default: break;
10526  }
10527  }
10528  res |= (cmds->needed > cmds->allocated + (cmds->memory.size - cmds->size)) ? NK_CONVERT_COMMAND_BUFFER_FULL: 0;
10529  res |= (vertices->needed > vertices->allocated) ? NK_CONVERT_VERTEX_BUFFER_FULL: 0;
10530  res |= (elements->needed > elements->allocated) ? NK_CONVERT_ELEMENT_BUFFER_FULL: 0;
10531  return res;
10532 }
10533 NK_API const struct nk_draw_command*
10534 nk__draw_begin(const struct nk_context *ctx,
10535  const struct nk_buffer *buffer)
10536 {
10537  return nk__draw_list_begin(&ctx->draw_list, buffer);
10538 }
10539 NK_API const struct nk_draw_command*
10540 nk__draw_end(const struct nk_context *ctx, const struct nk_buffer *buffer)
10541 {
10542  return nk__draw_list_end(&ctx->draw_list, buffer);
10543 }
10544 NK_API const struct nk_draw_command*
10545 nk__draw_next(const struct nk_draw_command *cmd,
10546  const struct nk_buffer *buffer, const struct nk_context *ctx)
10547 {
10548  return nk__draw_list_next(cmd, buffer, &ctx->draw_list);
10549 }
10550 #endif
10551 
10552 
10553 
10554 
10555 
10556 #ifdef NK_INCLUDE_FONT_BAKING
10557 /* -------------------------------------------------------------
10558  *
10559  * RECT PACK
10560  *
10561  * --------------------------------------------------------------*/
10562 /* stb_rect_pack.h - v0.05 - public domain - rectangle packing */
10563 /* Sean Barrett 2014 */
10564 #define NK_RP__MAXVAL 0xffff
10565 typedef unsigned short nk_rp_coord;
10566 
10567 struct nk_rp_rect {
10568  /* reserved for your use: */
10569  int id;
10570  /* input: */
10571  nk_rp_coord w, h;
10572  /* output: */
10573  nk_rp_coord x, y;
10574  int was_packed;
10575  /* non-zero if valid packing */
10576 }; /* 16 bytes, nominally */
10577 
10578 struct nk_rp_node {
10579  nk_rp_coord x,y;
10580  struct nk_rp_node *next;
10581 };
10582 
10583 struct nk_rp_context {
10584  int width;
10585  int height;
10586  int align;
10587  int init_mode;
10588  int heuristic;
10589  int num_nodes;
10590  struct nk_rp_node *active_head;
10591  struct nk_rp_node *free_head;
10592  struct nk_rp_node extra[2];
10593  /* we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' */
10594 };
10595 
10596 struct nk_rp__findresult {
10597  int x,y;
10598  struct nk_rp_node **prev_link;
10599 };
10600 
10601 enum NK_RP_HEURISTIC {
10602  NK_RP_HEURISTIC_Skyline_default=0,
10603  NK_RP_HEURISTIC_Skyline_BL_sortHeight = NK_RP_HEURISTIC_Skyline_default,
10604  NK_RP_HEURISTIC_Skyline_BF_sortHeight
10605 };
10606 enum NK_RP_INIT_STATE{NK_RP__INIT_skyline = 1};
10607 
10608 NK_INTERN void
10609 nk_rp_setup_allow_out_of_mem(struct nk_rp_context *context, int allow_out_of_mem)
10610 {
10611  if (allow_out_of_mem)
10612  /* if it's ok to run out of memory, then don't bother aligning them; */
10613  /* this gives better packing, but may fail due to OOM (even though */
10614  /* the rectangles easily fit). @TODO a smarter approach would be to only */
10615  /* quantize once we've hit OOM, then we could get rid of this parameter. */
10616  context->align = 1;
10617  else {
10618  /* if it's not ok to run out of memory, then quantize the widths */
10619  /* so that num_nodes is always enough nodes. */
10620  /* */
10621  /* I.e. num_nodes * align >= width */
10622  /* align >= width / num_nodes */
10623  /* align = ceil(width/num_nodes) */
10624  context->align = (context->width + context->num_nodes-1) / context->num_nodes;
10625  }
10626 }
10627 NK_INTERN void
10628 nk_rp_init_target(struct nk_rp_context *context, int width, int height,
10629  struct nk_rp_node *nodes, int num_nodes)
10630 {
10631  int i;
10632 #ifndef STBRP_LARGE_RECTS
10633  NK_ASSERT(width <= 0xffff && height <= 0xffff);
10634 #endif
10635 
10636  for (i=0; i < num_nodes-1; ++i)
10637  nodes[i].next = &nodes[i+1];
10638  nodes[i].next = 0;
10639  context->init_mode = NK_RP__INIT_skyline;
10640  context->heuristic = NK_RP_HEURISTIC_Skyline_default;
10641  context->free_head = &nodes[0];
10642  context->active_head = &context->extra[0];
10643  context->width = width;
10644  context->height = height;
10645  context->num_nodes = num_nodes;
10646  nk_rp_setup_allow_out_of_mem(context, 0);
10647 
10648  /* node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) */
10649  context->extra[0].x = 0;
10650  context->extra[0].y = 0;
10651  context->extra[0].next = &context->extra[1];
10652  context->extra[1].x = (nk_rp_coord) width;
10653  context->extra[1].y = 65535;
10654  context->extra[1].next = 0;
10655 }
10656 /* find minimum y position if it starts at x1 */
10657 NK_INTERN int
10658 nk_rp__skyline_find_min_y(struct nk_rp_context *c, struct nk_rp_node *first,
10659  int x0, int width, int *pwaste)
10660 {
10661  struct nk_rp_node *node = first;
10662  int x1 = x0 + width;
10663  int min_y, visited_width, waste_area;
10664  NK_ASSERT(first->x <= x0);
10665  NK_UNUSED(c);
10666 
10667  NK_ASSERT(node->next->x > x0);
10668  /* we ended up handling this in the caller for efficiency */
10669  NK_ASSERT(node->x <= x0);
10670 
10671  min_y = 0;
10672  waste_area = 0;
10673  visited_width = 0;
10674  while (node->x < x1)
10675  {
10676  if (node->y > min_y) {
10677  /* raise min_y higher. */
10678  /* we've accounted for all waste up to min_y, */
10679  /* but we'll now add more waste for everything we've visited */
10680  waste_area += visited_width * (node->y - min_y);
10681  min_y = node->y;
10682  /* the first time through, visited_width might be reduced */
10683  if (node->x < x0)
10684  visited_width += node->next->x - x0;
10685  else
10686  visited_width += node->next->x - node->x;
10687  } else {
10688  /* add waste area */
10689  int under_width = node->next->x - node->x;
10690  if (under_width + visited_width > width)
10691  under_width = width - visited_width;
10692  waste_area += under_width * (min_y - node->y);
10693  visited_width += under_width;
10694  }
10695  node = node->next;
10696  }
10697  *pwaste = waste_area;
10698  return min_y;
10699 }
10700 NK_INTERN struct nk_rp__findresult
10701 nk_rp__skyline_find_best_pos(struct nk_rp_context *c, int width, int height)
10702 {
10703  int best_waste = (1<<30), best_x, best_y = (1 << 30);
10704  struct nk_rp__findresult fr;
10705  struct nk_rp_node **prev, *node, *tail, **best = 0;
10706 
10707  /* align to multiple of c->align */
10708  width = (width + c->align - 1);
10709  width -= width % c->align;
10710  NK_ASSERT(width % c->align == 0);
10711 
10712  node = c->active_head;
10713  prev = &c->active_head;
10714  while (node->x + width <= c->width) {
10715  int y,waste;
10716  y = nk_rp__skyline_find_min_y(c, node, node->x, width, &waste);
10717  /* actually just want to test BL */
10718  if (c->heuristic == NK_RP_HEURISTIC_Skyline_BL_sortHeight) {
10719  /* bottom left */
10720  if (y < best_y) {
10721  best_y = y;
10722  best = prev;
10723  }
10724  } else {
10725  /* best-fit */
10726  if (y + height <= c->height) {
10727  /* can only use it if it first vertically */
10728  if (y < best_y || (y == best_y && waste < best_waste)) {
10729  best_y = y;
10730  best_waste = waste;
10731  best = prev;
10732  }
10733  }
10734  }
10735  prev = &node->next;
10736  node = node->next;
10737  }
10738  best_x = (best == 0) ? 0 : (*best)->x;
10739 
10740  /* if doing best-fit (BF), we also have to try aligning right edge to each node position */
10741  /* */
10742  /* e.g, if fitting */
10743  /* */
10744  /* ____________________ */
10745  /* |____________________| */
10746  /* */
10747  /* into */
10748  /* */
10749  /* | | */
10750  /* | ____________| */
10751  /* |____________| */
10752  /* */
10753  /* then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned */
10754  /* */
10755  /* This makes BF take about 2x the time */
10756  if (c->heuristic == NK_RP_HEURISTIC_Skyline_BF_sortHeight)
10757  {
10758  tail = c->active_head;
10759  node = c->active_head;
10760  prev = &c->active_head;
10761  /* find first node that's admissible */
10762  while (tail->x < width)
10763  tail = tail->next;
10764  while (tail)
10765  {
10766  int xpos = tail->x - width;
10767  int y,waste;
10768  NK_ASSERT(xpos >= 0);
10769  /* find the left position that matches this */
10770  while (node->next->x <= xpos) {
10771  prev = &node->next;
10772  node = node->next;
10773  }
10774  NK_ASSERT(node->next->x > xpos && node->x <= xpos);
10775  y = nk_rp__skyline_find_min_y(c, node, xpos, width, &waste);
10776  if (y + height < c->height) {
10777  if (y <= best_y) {
10778  if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
10779  best_x = xpos;
10780  NK_ASSERT(y <= best_y);
10781  best_y = y;
10782  best_waste = waste;
10783  best = prev;
10784  }
10785  }
10786  }
10787  tail = tail->next;
10788  }
10789  }
10790  fr.prev_link = best;
10791  fr.x = best_x;
10792  fr.y = best_y;
10793  return fr;
10794 }
10795 NK_INTERN struct nk_rp__findresult
10796 nk_rp__skyline_pack_rectangle(struct nk_rp_context *context, int width, int height)
10797 {
10798  /* find best position according to heuristic */
10799  struct nk_rp__findresult res = nk_rp__skyline_find_best_pos(context, width, height);
10800  struct nk_rp_node *node, *cur;
10801 
10802  /* bail if: */
10803  /* 1. it failed */
10804  /* 2. the best node doesn't fit (we don't always check this) */
10805  /* 3. we're out of memory */
10806  if (res.prev_link == 0 || res.y + height > context->height || context->free_head == 0) {
10807  res.prev_link = 0;
10808  return res;
10809  }
10810 
10811  /* on success, create new node */
10812  node = context->free_head;
10813  node->x = (nk_rp_coord) res.x;
10814  node->y = (nk_rp_coord) (res.y + height);
10815 
10816  context->free_head = node->next;
10817 
10818  /* insert the new node into the right starting point, and */
10819  /* let 'cur' point to the remaining nodes needing to be */
10820  /* stitched back in */
10821  cur = *res.prev_link;
10822  if (cur->x < res.x) {
10823  /* preserve the existing one, so start testing with the next one */
10824  struct nk_rp_node *next = cur->next;
10825  cur->next = node;
10826  cur = next;
10827  } else {
10828  *res.prev_link = node;
10829  }
10830 
10831  /* from here, traverse cur and free the nodes, until we get to one */
10832  /* that shouldn't be freed */
10833  while (cur->next && cur->next->x <= res.x + width) {
10834  struct nk_rp_node *next = cur->next;
10835  /* move the current node to the free list */
10836  cur->next = context->free_head;
10837  context->free_head = cur;
10838  cur = next;
10839  }
10840  /* stitch the list back in */
10841  node->next = cur;
10842 
10843  if (cur->x < res.x + width)
10844  cur->x = (nk_rp_coord) (res.x + width);
10845  return res;
10846 }
10847 NK_INTERN int
10848 nk_rect_height_compare(const void *a, const void *b)
10849 {
10850  const struct nk_rp_rect *p = (const struct nk_rp_rect *) a;
10851  const struct nk_rp_rect *q = (const struct nk_rp_rect *) b;
10852  if (p->h > q->h)
10853  return -1;
10854  if (p->h < q->h)
10855  return 1;
10856  return (p->w > q->w) ? -1 : (p->w < q->w);
10857 }
10858 NK_INTERN int
10859 nk_rect_original_order(const void *a, const void *b)
10860 {
10861  const struct nk_rp_rect *p = (const struct nk_rp_rect *) a;
10862  const struct nk_rp_rect *q = (const struct nk_rp_rect *) b;
10863  return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
10864 }
10865 NK_INTERN void
10866 nk_rp_qsort(struct nk_rp_rect *array, unsigned int len, int(*cmp)(const void*,const void*))
10867 {
10868  /* iterative quick sort */
10869  #define NK_MAX_SORT_STACK 64
10870  unsigned right, left = 0, stack[NK_MAX_SORT_STACK], pos = 0;
10871  unsigned seed = len/2 * 69069+1;
10872  for (;;) {
10873  for (; left+1 < len; len++) {
10874  struct nk_rp_rect pivot, tmp;
10875  if (pos == NK_MAX_SORT_STACK) len = stack[pos = 0];
10876  pivot = array[left+seed%(len-left)];
10877  seed = seed * 69069 + 1;
10878  stack[pos++] = len;
10879  for (right = left-1;;) {
10880  while (cmp(&array[++right], &pivot) < 0);
10881  while (cmp(&pivot, &array[--len]) < 0);
10882  if (right >= len) break;
10883  tmp = array[right];
10884  array[right] = array[len];
10885  array[len] = tmp;
10886  }
10887  }
10888  if (pos == 0) break;
10889  left = len;
10890  len = stack[--pos];
10891  }
10892  #undef NK_MAX_SORT_STACK
10893 }
10894 NK_INTERN void
10895 nk_rp_pack_rects(struct nk_rp_context *context, struct nk_rp_rect *rects, int num_rects)
10896 {
10897  int i;
10898  /* we use the 'was_packed' field internally to allow sorting/unsorting */
10899  for (i=0; i < num_rects; ++i) {
10900  rects[i].was_packed = i;
10901  }
10902 
10903  /* sort according to heuristic */
10904  nk_rp_qsort(rects, (unsigned)num_rects, nk_rect_height_compare);
10905 
10906  for (i=0; i < num_rects; ++i) {
10907  struct nk_rp__findresult fr = nk_rp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
10908  if (fr.prev_link) {
10909  rects[i].x = (nk_rp_coord) fr.x;
10910  rects[i].y = (nk_rp_coord) fr.y;
10911  } else {
10912  rects[i].x = rects[i].y = NK_RP__MAXVAL;
10913  }
10914  }
10915 
10916  /* unsort */
10917  nk_rp_qsort(rects, (unsigned)num_rects, nk_rect_original_order);
10918 
10919  /* set was_packed flags */
10920  for (i=0; i < num_rects; ++i)
10921  rects[i].was_packed = !(rects[i].x == NK_RP__MAXVAL && rects[i].y == NK_RP__MAXVAL);
10922 }
10923 
10924 /*
10925  * ==============================================================
10926  *
10927  * TRUETYPE
10928  *
10929  * ===============================================================
10930  */
10931 /* stb_truetype.h - v1.07 - public domain */
10932 #define NK_TT_MAX_OVERSAMPLE 8
10933 #define NK_TT__OVER_MASK (NK_TT_MAX_OVERSAMPLE-1)
10934 
10935 struct nk_tt_bakedchar {
10936  unsigned short x0,y0,x1,y1;
10937  /* coordinates of bbox in bitmap */
10938  float xoff,yoff,xadvance;
10939 };
10940 
10941 struct nk_tt_aligned_quad{
10942  float x0,y0,s0,t0; /* top-left */
10943  float x1,y1,s1,t1; /* bottom-right */
10944 };
10945 
10946 struct nk_tt_packedchar {
10947  unsigned short x0,y0,x1,y1;
10948  /* coordinates of bbox in bitmap */
10949  float xoff,yoff,xadvance;
10950  float xoff2,yoff2;
10951 };
10952 
10953 struct nk_tt_pack_range {
10954  float font_size;
10955  int first_unicode_codepoint_in_range;
10956  /* if non-zero, then the chars are continuous, and this is the first codepoint */
10957  int *array_of_unicode_codepoints;
10958  /* if non-zero, then this is an array of unicode codepoints */
10959  int num_chars;
10960  struct nk_tt_packedchar *chardata_for_range; /* output */
10961  unsigned char h_oversample, v_oversample;
10962  /* don't set these, they're used internally */
10963 };
10964 
10965 struct nk_tt_pack_context {
10966  void *pack_info;
10967  int width;
10968  int height;
10969  int stride_in_bytes;
10970  int padding;
10971  unsigned int h_oversample, v_oversample;
10972  unsigned char *pixels;
10973  void *nodes;
10974 };
10975 
10976 struct nk_tt_fontinfo {
10977  const unsigned char* data; /* pointer to .ttf file */
10978  int fontstart;/* offset of start of font */
10979  int numGlyphs;/* number of glyphs, needed for range checking */
10980  int loca,head,glyf,hhea,hmtx,kern; /* table locations as offset from start of .ttf */
10981  int index_map; /* a cmap mapping for our chosen character encoding */
10982  int indexToLocFormat; /* format needed to map from glyph index to glyph */
10983 };
10984 
10985 enum {
10986  NK_TT_vmove=1,
10987  NK_TT_vline,
10988  NK_TT_vcurve
10989 };
10990 
10991 struct nk_tt_vertex {
10992  short x,y,cx,cy;
10993  unsigned char type,padding;
10994 };
10995 
10996 struct nk_tt__bitmap{
10997  int w,h,stride;
10998  unsigned char *pixels;
10999 };
11000 
11001 struct nk_tt__hheap_chunk {
11002  struct nk_tt__hheap_chunk *next;
11003 };
11004 struct nk_tt__hheap {
11005  struct nk_allocator alloc;
11006  struct nk_tt__hheap_chunk *head;
11007  void *first_free;
11008  int num_remaining_in_head_chunk;
11009 };
11010 
11011 struct nk_tt__edge {
11012  float x0,y0, x1,y1;
11013  int invert;
11014 };
11015 
11016 struct nk_tt__active_edge {
11017  struct nk_tt__active_edge *next;
11018  float fx,fdx,fdy;
11019  float direction;
11020  float sy;
11021  float ey;
11022 };
11023 struct nk_tt__point {float x,y;};
11024 
11025 #define NK_TT_MACSTYLE_DONTCARE 0
11026 #define NK_TT_MACSTYLE_BOLD 1
11027 #define NK_TT_MACSTYLE_ITALIC 2
11028 #define NK_TT_MACSTYLE_UNDERSCORE 4
11029 #define NK_TT_MACSTYLE_NONE 8
11030 /* <= not same as 0, this makes us check the bitfield is 0 */
11031 
11032 enum { /* platformID */
11033  NK_TT_PLATFORM_ID_UNICODE =0,
11034  NK_TT_PLATFORM_ID_MAC =1,
11035  NK_TT_PLATFORM_ID_ISO =2,
11036  NK_TT_PLATFORM_ID_MICROSOFT =3
11037 };
11038 
11039 enum { /* encodingID for NK_TT_PLATFORM_ID_UNICODE */
11040  NK_TT_UNICODE_EID_UNICODE_1_0 =0,
11041  NK_TT_UNICODE_EID_UNICODE_1_1 =1,
11042  NK_TT_UNICODE_EID_ISO_10646 =2,
11043  NK_TT_UNICODE_EID_UNICODE_2_0_BMP=3,
11044  NK_TT_UNICODE_EID_UNICODE_2_0_FULL=4
11045 };
11046 
11047 enum { /* encodingID for NK_TT_PLATFORM_ID_MICROSOFT */
11048  NK_TT_MS_EID_SYMBOL =0,
11049  NK_TT_MS_EID_UNICODE_BMP =1,
11050  NK_TT_MS_EID_SHIFTJIS =2,
11051  NK_TT_MS_EID_UNICODE_FULL =10
11052 };
11053 
11054 enum { /* encodingID for NK_TT_PLATFORM_ID_MAC; same as Script Manager codes */
11055  NK_TT_MAC_EID_ROMAN =0, NK_TT_MAC_EID_ARABIC =4,
11056  NK_TT_MAC_EID_JAPANESE =1, NK_TT_MAC_EID_HEBREW =5,
11057  NK_TT_MAC_EID_CHINESE_TRAD =2, NK_TT_MAC_EID_GREEK =6,
11058  NK_TT_MAC_EID_KOREAN =3, NK_TT_MAC_EID_RUSSIAN =7
11059 };
11060 
11061 enum { /* languageID for NK_TT_PLATFORM_ID_MICROSOFT; same as LCID... */
11062  /* problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs */
11063  NK_TT_MS_LANG_ENGLISH =0x0409, NK_TT_MS_LANG_ITALIAN =0x0410,
11064  NK_TT_MS_LANG_CHINESE =0x0804, NK_TT_MS_LANG_JAPANESE =0x0411,
11065  NK_TT_MS_LANG_DUTCH =0x0413, NK_TT_MS_LANG_KOREAN =0x0412,
11066  NK_TT_MS_LANG_FRENCH =0x040c, NK_TT_MS_LANG_RUSSIAN =0x0419,
11067  NK_TT_MS_LANG_GERMAN =0x0407, NK_TT_MS_LANG_SPANISH =0x0409,
11068  NK_TT_MS_LANG_HEBREW =0x040d, NK_TT_MS_LANG_SWEDISH =0x041D
11069 };
11070 
11071 enum { /* languageID for NK_TT_PLATFORM_ID_MAC */
11072  NK_TT_MAC_LANG_ENGLISH =0 , NK_TT_MAC_LANG_JAPANESE =11,
11073  NK_TT_MAC_LANG_ARABIC =12, NK_TT_MAC_LANG_KOREAN =23,
11074  NK_TT_MAC_LANG_DUTCH =4 , NK_TT_MAC_LANG_RUSSIAN =32,
11075  NK_TT_MAC_LANG_FRENCH =1 , NK_TT_MAC_LANG_SPANISH =6 ,
11076  NK_TT_MAC_LANG_GERMAN =2 , NK_TT_MAC_LANG_SWEDISH =5 ,
11077  NK_TT_MAC_LANG_HEBREW =10, NK_TT_MAC_LANG_CHINESE_SIMPLIFIED =33,
11078  NK_TT_MAC_LANG_ITALIAN =3 , NK_TT_MAC_LANG_CHINESE_TRAD =19
11079 };
11080 
11081 #define nk_ttBYTE(p) (* (const nk_byte *) (p))
11082 #define nk_ttCHAR(p) (* (const char *) (p))
11083 
11084 #if defined(NK_BIGENDIAN) && !defined(NK_ALLOW_UNALIGNED_TRUETYPE)
11085  #define nk_ttUSHORT(p) (* (nk_ushort *) (p))
11086  #define nk_ttSHORT(p) (* (nk_short *) (p))
11087  #define nk_ttULONG(p) (* (nk_uint *) (p))
11088  #define nk_ttLONG(p) (* (nk_int *) (p))
11089 #else
11090  static nk_ushort nk_ttUSHORT(const nk_byte *p) { return (nk_ushort)(p[0]*256 + p[1]); }
11091  static nk_short nk_ttSHORT(const nk_byte *p) { return (nk_short)(p[0]*256 + p[1]); }
11092  static nk_uint nk_ttULONG(const nk_byte *p) { return (nk_uint)((p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]); }
11093 #endif
11094 
11095 #define nk_tt_tag4(p,c0,c1,c2,c3)\
11096  ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
11097 #define nk_tt_tag(p,str) nk_tt_tag4(p,str[0],str[1],str[2],str[3])
11098 
11099 NK_INTERN int nk_tt_GetGlyphShape(const struct nk_tt_fontinfo *info, struct nk_allocator *alloc,
11100  int glyph_index, struct nk_tt_vertex **pvertices);
11101 
11103 nk_tt__find_table(const nk_byte *data, nk_uint fontstart, const char *tag)
11104 {
11105  /* @OPTIMIZE: binary search */
11106  nk_int num_tables = nk_ttUSHORT(data+fontstart+4);
11107  nk_uint tabledir = fontstart + 12;
11108  nk_int i;
11109  for (i = 0; i < num_tables; ++i) {
11110  nk_uint loc = tabledir + (nk_uint)(16*i);
11111  if (nk_tt_tag(data+loc+0, tag))
11112  return nk_ttULONG(data+loc+8);
11113  }
11114  return 0;
11115 }
11116 NK_INTERN int
11117 nk_tt_InitFont(struct nk_tt_fontinfo *info, const unsigned char *data2, int fontstart)
11118 {
11119  nk_uint cmap, t;
11120  nk_int i,numTables;
11121  const nk_byte *data = (const nk_byte *) data2;
11122 
11123  info->data = data;
11124  info->fontstart = fontstart;
11125 
11126  cmap = nk_tt__find_table(data, (nk_uint)fontstart, "cmap"); /* required */
11127  info->loca = (int)nk_tt__find_table(data, (nk_uint)fontstart, "loca"); /* required */
11128  info->head = (int)nk_tt__find_table(data, (nk_uint)fontstart, "head"); /* required */
11129  info->glyf = (int)nk_tt__find_table(data, (nk_uint)fontstart, "glyf"); /* required */
11130  info->hhea = (int)nk_tt__find_table(data, (nk_uint)fontstart, "hhea"); /* required */
11131  info->hmtx = (int)nk_tt__find_table(data, (nk_uint)fontstart, "hmtx"); /* required */
11132  info->kern = (int)nk_tt__find_table(data, (nk_uint)fontstart, "kern"); /* not required */
11133  if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx)
11134  return 0;
11135 
11136  t = nk_tt__find_table(data, (nk_uint)fontstart, "maxp");
11137  if (t) info->numGlyphs = nk_ttUSHORT(data+t+4);
11138  else info->numGlyphs = 0xffff;
11139 
11140  /* find a cmap encoding table we understand *now* to avoid searching */
11141  /* later. (todo: could make this installable) */
11142  /* the same regardless of glyph. */
11143  numTables = nk_ttUSHORT(data + cmap + 2);
11144  info->index_map = 0;
11145  for (i=0; i < numTables; ++i)
11146  {
11147  nk_uint encoding_record = cmap + 4 + 8 * (nk_uint)i;
11148  /* find an encoding we understand: */
11149  switch(nk_ttUSHORT(data+encoding_record)) {
11150  case NK_TT_PLATFORM_ID_MICROSOFT:
11151  switch (nk_ttUSHORT(data+encoding_record+2)) {
11152  case NK_TT_MS_EID_UNICODE_BMP:
11153  case NK_TT_MS_EID_UNICODE_FULL:
11154  /* MS/Unicode */
11155  info->index_map = (int)(cmap + nk_ttULONG(data+encoding_record+4));
11156  break;
11157  default: break;
11158  } break;
11159  case NK_TT_PLATFORM_ID_UNICODE:
11160  /* Mac/iOS has these */
11161  /* all the encodingIDs are unicode, so we don't bother to check it */
11162  info->index_map = (int)(cmap + nk_ttULONG(data+encoding_record+4));
11163  break;
11164  default: break;
11165  }
11166  }
11167  if (info->index_map == 0)
11168  return 0;
11169  info->indexToLocFormat = nk_ttUSHORT(data+info->head + 50);
11170  return 1;
11171 }
11172 NK_INTERN int
11173 nk_tt_FindGlyphIndex(const struct nk_tt_fontinfo *info, int unicode_codepoint)
11174 {
11175  const nk_byte *data = info->data;
11176  nk_uint index_map = (nk_uint)info->index_map;
11177 
11178  nk_ushort format = nk_ttUSHORT(data + index_map + 0);
11179  if (format == 0) { /* apple byte encoding */
11180  nk_int bytes = nk_ttUSHORT(data + index_map + 2);
11181  if (unicode_codepoint < bytes-6)
11182  return nk_ttBYTE(data + index_map + 6 + unicode_codepoint);
11183  return 0;
11184  } else if (format == 6) {
11185  nk_uint first = nk_ttUSHORT(data + index_map + 6);
11186  nk_uint count = nk_ttUSHORT(data + index_map + 8);
11187  if ((nk_uint) unicode_codepoint >= first && (nk_uint) unicode_codepoint < first+count)
11188  return nk_ttUSHORT(data + index_map + 10 + (unicode_codepoint - (int)first)*2);
11189  return 0;
11190  } else if (format == 2) {
11191  NK_ASSERT(0); /* @TODO: high-byte mapping for japanese/chinese/korean */
11192  return 0;
11193  } else if (format == 4) { /* standard mapping for windows fonts: binary search collection of ranges */
11194  nk_ushort segcount = nk_ttUSHORT(data+index_map+6) >> 1;
11195  nk_ushort searchRange = nk_ttUSHORT(data+index_map+8) >> 1;
11196  nk_ushort entrySelector = nk_ttUSHORT(data+index_map+10);
11197  nk_ushort rangeShift = nk_ttUSHORT(data+index_map+12) >> 1;
11198 
11199  /* do a binary search of the segments */
11200  nk_uint endCount = index_map + 14;
11201  nk_uint search = endCount;
11202 
11203  if (unicode_codepoint > 0xffff)
11204  return 0;
11205 
11206  /* they lie from endCount .. endCount + segCount */
11207  /* but searchRange is the nearest power of two, so... */
11208  if (unicode_codepoint >= nk_ttUSHORT(data + search + rangeShift*2))
11209  search += (nk_uint)(rangeShift*2);
11210 
11211  /* now decrement to bias correctly to find smallest */
11212  search -= 2;
11213  while (entrySelector) {
11214  nk_ushort end;
11215  searchRange >>= 1;
11216  end = nk_ttUSHORT(data + search + searchRange*2);
11217  if (unicode_codepoint > end)
11218  search += (nk_uint)(searchRange*2);
11219  --entrySelector;
11220  }
11221  search += 2;
11222 
11223  {
11224  nk_ushort offset, start;
11225  nk_ushort item = (nk_ushort) ((search - endCount) >> 1);
11226 
11227  NK_ASSERT(unicode_codepoint <= nk_ttUSHORT(data + endCount + 2*item));
11228  start = nk_ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
11229  if (unicode_codepoint < start)
11230  return 0;
11231 
11232  offset = nk_ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
11233  if (offset == 0)
11234  return (nk_ushort) (unicode_codepoint + nk_ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item));
11235 
11236  return nk_ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
11237  }
11238  } else if (format == 12 || format == 13) {
11239  nk_uint ngroups = nk_ttULONG(data+index_map+12);
11240  nk_int low,high;
11241  low = 0; high = (nk_int)ngroups;
11242  /* Binary search the right group. */
11243  while (low < high) {
11244  nk_int mid = low + ((high-low) >> 1); /* rounds down, so low <= mid < high */
11245  nk_uint start_char = nk_ttULONG(data+index_map+16+mid*12);
11246  nk_uint end_char = nk_ttULONG(data+index_map+16+mid*12+4);
11247  if ((nk_uint) unicode_codepoint < start_char)
11248  high = mid;
11249  else if ((nk_uint) unicode_codepoint > end_char)
11250  low = mid+1;
11251  else {
11252  nk_uint start_glyph = nk_ttULONG(data+index_map+16+mid*12+8);
11253  if (format == 12)
11254  return (int)start_glyph + (int)unicode_codepoint - (int)start_char;
11255  else /* format == 13 */
11256  return (int)start_glyph;
11257  }
11258  }
11259  return 0; /* not found */
11260  }
11261  /* @TODO */
11262  NK_ASSERT(0);
11263  return 0;
11264 }
11265 NK_INTERN void
11266 nk_tt_setvertex(struct nk_tt_vertex *v, nk_byte type, nk_int x, nk_int y, nk_int cx, nk_int cy)
11267 {
11268  v->type = type;
11269  v->x = (nk_short) x;
11270  v->y = (nk_short) y;
11271  v->cx = (nk_short) cx;
11272  v->cy = (nk_short) cy;
11273 }
11274 NK_INTERN int
11275 nk_tt__GetGlyfOffset(const struct nk_tt_fontinfo *info, int glyph_index)
11276 {
11277  int g1,g2;
11278  if (glyph_index >= info->numGlyphs) return -1; /* glyph index out of range */
11279  if (info->indexToLocFormat >= 2) return -1; /* unknown index->glyph map format */
11280 
11281  if (info->indexToLocFormat == 0) {
11282  g1 = info->glyf + nk_ttUSHORT(info->data + info->loca + glyph_index * 2) * 2;
11283  g2 = info->glyf + nk_ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2;
11284  } else {
11285  g1 = info->glyf + (int)nk_ttULONG (info->data + info->loca + glyph_index * 4);
11286  g2 = info->glyf + (int)nk_ttULONG (info->data + info->loca + glyph_index * 4 + 4);
11287  }
11288  return g1==g2 ? -1 : g1; /* if length is 0, return -1 */
11289 }
11290 NK_INTERN int
11291 nk_tt_GetGlyphBox(const struct nk_tt_fontinfo *info, int glyph_index,
11292  int *x0, int *y0, int *x1, int *y1)
11293 {
11294  int g = nk_tt__GetGlyfOffset(info, glyph_index);
11295  if (g < 0) return 0;
11296 
11297  if (x0) *x0 = nk_ttSHORT(info->data + g + 2);
11298  if (y0) *y0 = nk_ttSHORT(info->data + g + 4);
11299  if (x1) *x1 = nk_ttSHORT(info->data + g + 6);
11300  if (y1) *y1 = nk_ttSHORT(info->data + g + 8);
11301  return 1;
11302 }
11303 NK_INTERN int
11304 nk_tt__close_shape(struct nk_tt_vertex *vertices, int num_vertices, int was_off,
11305  int start_off, nk_int sx, nk_int sy, nk_int scx, nk_int scy, nk_int cx, nk_int cy)
11306 {
11307  if (start_off) {
11308  if (was_off)
11309  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy);
11310  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, sx,sy,scx,scy);
11311  } else {
11312  if (was_off)
11313  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve,sx,sy,cx,cy);
11314  else
11315  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vline,sx,sy,0,0);
11316  }
11317  return num_vertices;
11318 }
11319 NK_INTERN int
11320 nk_tt_GetGlyphShape(const struct nk_tt_fontinfo *info, struct nk_allocator *alloc,
11321  int glyph_index, struct nk_tt_vertex **pvertices)
11322 {
11323  nk_short numberOfContours;
11324  const nk_byte *endPtsOfContours;
11325  const nk_byte *data = info->data;
11326  struct nk_tt_vertex *vertices=0;
11327  int num_vertices=0;
11328  int g = nk_tt__GetGlyfOffset(info, glyph_index);
11329  *pvertices = 0;
11330 
11331  if (g < 0) return 0;
11332  numberOfContours = nk_ttSHORT(data + g);
11333  if (numberOfContours > 0) {
11334  nk_byte flags=0,flagcount;
11335  nk_int ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0;
11336  nk_int x,y,cx,cy,sx,sy, scx,scy;
11337  const nk_byte *points;
11338  endPtsOfContours = (data + g + 10);
11339  ins = nk_ttUSHORT(data + g + 10 + numberOfContours * 2);
11340  points = data + g + 10 + numberOfContours * 2 + 2 + ins;
11341 
11342  n = 1+nk_ttUSHORT(endPtsOfContours + numberOfContours*2-2);
11343  m = n + 2*numberOfContours; /* a loose bound on how many vertices we might need */
11344  vertices = (struct nk_tt_vertex *)alloc->alloc(alloc->userdata, 0, (nk_size)m * sizeof(vertices[0]));
11345  if (vertices == 0)
11346  return 0;
11347 
11348  next_move = 0;
11349  flagcount=0;
11350 
11351  /* in first pass, we load uninterpreted data into the allocated array */
11352  /* above, shifted to the end of the array so we won't overwrite it when */
11353  /* we create our final data starting from the front */
11354  off = m - n; /* starting offset for uninterpreted data, regardless of how m ends up being calculated */
11355 
11356  /* first load flags */
11357  for (i=0; i < n; ++i) {
11358  if (flagcount == 0) {
11359  flags = *points++;
11360  if (flags & 8)
11361  flagcount = *points++;
11362  } else --flagcount;
11363  vertices[off+i].type = flags;
11364  }
11365 
11366  /* now load x coordinates */
11367  x=0;
11368  for (i=0; i < n; ++i) {
11369  flags = vertices[off+i].type;
11370  if (flags & 2) {
11371  nk_short dx = *points++;
11372  x += (flags & 16) ? dx : -dx; /* ??? */
11373  } else {
11374  if (!(flags & 16)) {
11375  x = x + (nk_short) (points[0]*256 + points[1]);
11376  points += 2;
11377  }
11378  }
11379  vertices[off+i].x = (nk_short) x;
11380  }
11381 
11382  /* now load y coordinates */
11383  y=0;
11384  for (i=0; i < n; ++i) {
11385  flags = vertices[off+i].type;
11386  if (flags & 4) {
11387  nk_short dy = *points++;
11388  y += (flags & 32) ? dy : -dy; /* ??? */
11389  } else {
11390  if (!(flags & 32)) {
11391  y = y + (nk_short) (points[0]*256 + points[1]);
11392  points += 2;
11393  }
11394  }
11395  vertices[off+i].y = (nk_short) y;
11396  }
11397 
11398  /* now convert them to our format */
11399  num_vertices=0;
11400  sx = sy = cx = cy = scx = scy = 0;
11401  for (i=0; i < n; ++i)
11402  {
11403  flags = vertices[off+i].type;
11404  x = (nk_short) vertices[off+i].x;
11405  y = (nk_short) vertices[off+i].y;
11406 
11407  if (next_move == i) {
11408  if (i != 0)
11409  num_vertices = nk_tt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
11410 
11411  /* now start the new one */
11412  start_off = !(flags & 1);
11413  if (start_off) {
11414  /* if we start off with an off-curve point, then when we need to find a point on the curve */
11415  /* where we can start, and we need to save some state for when we wraparound. */
11416  scx = x;
11417  scy = y;
11418  if (!(vertices[off+i+1].type & 1)) {
11419  /* next point is also a curve point, so interpolate an on-point curve */
11420  sx = (x + (nk_int) vertices[off+i+1].x) >> 1;
11421  sy = (y + (nk_int) vertices[off+i+1].y) >> 1;
11422  } else {
11423  /* otherwise just use the next point as our start point */
11424  sx = (nk_int) vertices[off+i+1].x;
11425  sy = (nk_int) vertices[off+i+1].y;
11426  ++i; /* we're using point i+1 as the starting point, so skip it */
11427  }
11428  } else {
11429  sx = x;
11430  sy = y;
11431  }
11432  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vmove,sx,sy,0,0);
11433  was_off = 0;
11434  next_move = 1 + nk_ttUSHORT(endPtsOfContours+j*2);
11435  ++j;
11436  } else {
11437  if (!(flags & 1))
11438  { /* if it's a curve */
11439  if (was_off) /* two off-curve control points in a row means interpolate an on-curve midpoint */
11440  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy);
11441  cx = x;
11442  cy = y;
11443  was_off = 1;
11444  } else {
11445  if (was_off)
11446  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, x,y, cx, cy);
11447  else nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vline, x,y,0,0);
11448  was_off = 0;
11449  }
11450  }
11451  }
11452  num_vertices = nk_tt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
11453  } else if (numberOfContours == -1) {
11454  /* Compound shapes. */
11455  int more = 1;
11456  const nk_byte *comp = data + g + 10;
11457  num_vertices = 0;
11458  vertices = 0;
11459 
11460  while (more)
11461  {
11462  nk_ushort flags, gidx;
11463  int comp_num_verts = 0, i;
11464  struct nk_tt_vertex *comp_verts = 0, *tmp = 0;
11465  float mtx[6] = {1,0,0,1,0,0}, m, n;
11466 
11467  flags = (nk_ushort)nk_ttSHORT(comp); comp+=2;
11468  gidx = (nk_ushort)nk_ttSHORT(comp); comp+=2;
11469 
11470  if (flags & 2) { /* XY values */
11471  if (flags & 1) { /* shorts */
11472  mtx[4] = nk_ttSHORT(comp); comp+=2;
11473  mtx[5] = nk_ttSHORT(comp); comp+=2;
11474  } else {
11475  mtx[4] = nk_ttCHAR(comp); comp+=1;
11476  mtx[5] = nk_ttCHAR(comp); comp+=1;
11477  }
11478  } else {
11479  /* @TODO handle matching point */
11480  NK_ASSERT(0);
11481  }
11482  if (flags & (1<<3)) { /* WE_HAVE_A_SCALE */
11483  mtx[0] = mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11484  mtx[1] = mtx[2] = 0;
11485  } else if (flags & (1<<6)) { /* WE_HAVE_AN_X_AND_YSCALE */
11486  mtx[0] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11487  mtx[1] = mtx[2] = 0;
11488  mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11489  } else if (flags & (1<<7)) { /* WE_HAVE_A_TWO_BY_TWO */
11490  mtx[0] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11491  mtx[1] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11492  mtx[2] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11493  mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11494  }
11495 
11496  /* Find transformation scales. */
11497  m = (float) NK_SQRT(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
11498  n = (float) NK_SQRT(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
11499 
11500  /* Get indexed glyph. */
11501  comp_num_verts = nk_tt_GetGlyphShape(info, alloc, gidx, &comp_verts);
11502  if (comp_num_verts > 0)
11503  {
11504  /* Transform vertices. */
11505  for (i = 0; i < comp_num_verts; ++i) {
11506  struct nk_tt_vertex* v = &comp_verts[i];
11507  short x,y;
11508  x=v->x; y=v->y;
11509  v->x = (short)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
11510  v->y = (short)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
11511  x=v->cx; y=v->cy;
11512  v->cx = (short)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
11513  v->cy = (short)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
11514  }
11515  /* Append vertices. */
11516  tmp = (struct nk_tt_vertex*)alloc->alloc(alloc->userdata, 0,
11517  (nk_size)(num_vertices+comp_num_verts)*sizeof(struct nk_tt_vertex));
11518  if (!tmp) {
11519  if (vertices) alloc->free(alloc->userdata, vertices);
11520  if (comp_verts) alloc->free(alloc->userdata, comp_verts);
11521  return 0;
11522  }
11523  if (num_vertices > 0) NK_MEMCPY(tmp, vertices, (nk_size)num_vertices*sizeof(struct nk_tt_vertex));
11524  NK_MEMCPY(tmp+num_vertices, comp_verts, (nk_size)comp_num_verts*sizeof(struct nk_tt_vertex));
11525  if (vertices) alloc->free(alloc->userdata,vertices);
11526  vertices = tmp;
11527  alloc->free(alloc->userdata,comp_verts);
11528  num_vertices += comp_num_verts;
11529  }
11530  /* More components ? */
11531  more = flags & (1<<5);
11532  }
11533  } else if (numberOfContours < 0) {
11534  /* @TODO other compound variations? */
11535  NK_ASSERT(0);
11536  } else {
11537  /* numberOfCounters == 0, do nothing */
11538  }
11539  *pvertices = vertices;
11540  return num_vertices;
11541 }
11542 NK_INTERN void
11543 nk_tt_GetGlyphHMetrics(const struct nk_tt_fontinfo *info, int glyph_index,
11544  int *advanceWidth, int *leftSideBearing)
11545 {
11546  nk_ushort numOfLongHorMetrics = nk_ttUSHORT(info->data+info->hhea + 34);
11547  if (glyph_index < numOfLongHorMetrics) {
11548  if (advanceWidth)
11549  *advanceWidth = nk_ttSHORT(info->data + info->hmtx + 4*glyph_index);
11550  if (leftSideBearing)
11551  *leftSideBearing = nk_ttSHORT(info->data + info->hmtx + 4*glyph_index + 2);
11552  } else {
11553  if (advanceWidth)
11554  *advanceWidth = nk_ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1));
11555  if (leftSideBearing)
11556  *leftSideBearing = nk_ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics));
11557  }
11558 }
11559 NK_INTERN void
11560 nk_tt_GetFontVMetrics(const struct nk_tt_fontinfo *info,
11561  int *ascent, int *descent, int *lineGap)
11562 {
11563  if (ascent ) *ascent = nk_ttSHORT(info->data+info->hhea + 4);
11564  if (descent) *descent = nk_ttSHORT(info->data+info->hhea + 6);
11565  if (lineGap) *lineGap = nk_ttSHORT(info->data+info->hhea + 8);
11566 }
11567 NK_INTERN float
11568 nk_tt_ScaleForPixelHeight(const struct nk_tt_fontinfo *info, float height)
11569 {
11570  int fheight = nk_ttSHORT(info->data + info->hhea + 4) - nk_ttSHORT(info->data + info->hhea + 6);
11571  return (float) height / (float)fheight;
11572 }
11573 NK_INTERN float
11574 nk_tt_ScaleForMappingEmToPixels(const struct nk_tt_fontinfo *info, float pixels)
11575 {
11576  int unitsPerEm = nk_ttUSHORT(info->data + info->head + 18);
11577  return pixels / (float)unitsPerEm;
11578 }
11579 
11580 /*-------------------------------------------------------------
11581  * antialiasing software rasterizer
11582  * --------------------------------------------------------------*/
11583 NK_INTERN void
11584 nk_tt_GetGlyphBitmapBoxSubpixel(const struct nk_tt_fontinfo *font,
11585  int glyph, float scale_x, float scale_y,float shift_x, float shift_y,
11586  int *ix0, int *iy0, int *ix1, int *iy1)
11587 {
11588  int x0,y0,x1,y1;
11589  if (!nk_tt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
11590  /* e.g. space character */
11591  if (ix0) *ix0 = 0;
11592  if (iy0) *iy0 = 0;
11593  if (ix1) *ix1 = 0;
11594  if (iy1) *iy1 = 0;
11595  } else {
11596  /* move to integral bboxes (treating pixels as little squares, what pixels get touched)? */
11597  if (ix0) *ix0 = nk_ifloorf((float)x0 * scale_x + shift_x);
11598  if (iy0) *iy0 = nk_ifloorf((float)-y1 * scale_y + shift_y);
11599  if (ix1) *ix1 = nk_iceilf ((float)x1 * scale_x + shift_x);
11600  if (iy1) *iy1 = nk_iceilf ((float)-y0 * scale_y + shift_y);
11601  }
11602 }
11603 NK_INTERN void
11604 nk_tt_GetGlyphBitmapBox(const struct nk_tt_fontinfo *font, int glyph,
11605  float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1)
11606 {
11607  nk_tt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1);
11608 }
11609 
11610 /*-------------------------------------------------------------
11611  * Rasterizer
11612  * --------------------------------------------------------------*/
11613 NK_INTERN void*
11614 nk_tt__hheap_alloc(struct nk_tt__hheap *hh, nk_size size)
11615 {
11616  if (hh->first_free) {
11617  void *p = hh->first_free;
11618  hh->first_free = * (void **) p;
11619  return p;
11620  } else {
11621  if (hh->num_remaining_in_head_chunk == 0) {
11622  int count = (size < 32 ? 2000 : size < 128 ? 800 : 100);
11623  struct nk_tt__hheap_chunk *c = (struct nk_tt__hheap_chunk *)
11624  hh->alloc.alloc(hh->alloc.userdata, 0,
11625  sizeof(struct nk_tt__hheap_chunk) + size * (nk_size)count);
11626  if (c == 0) return 0;
11627  c->next = hh->head;
11628  hh->head = c;
11629  hh->num_remaining_in_head_chunk = count;
11630  }
11631  --hh->num_remaining_in_head_chunk;
11632  return (char *) (hh->head) + size * (nk_size)hh->num_remaining_in_head_chunk;
11633  }
11634 }
11635 NK_INTERN void
11636 nk_tt__hheap_free(struct nk_tt__hheap *hh, void *p)
11637 {
11638  *(void **) p = hh->first_free;
11639  hh->first_free = p;
11640 }
11641 NK_INTERN void
11642 nk_tt__hheap_cleanup(struct nk_tt__hheap *hh)
11643 {
11644  struct nk_tt__hheap_chunk *c = hh->head;
11645  while (c) {
11646  struct nk_tt__hheap_chunk *n = c->next;
11647  hh->alloc.free(hh->alloc.userdata, c);
11648  c = n;
11649  }
11650 }
11651 NK_INTERN struct nk_tt__active_edge*
11652 nk_tt__new_active(struct nk_tt__hheap *hh, struct nk_tt__edge *e,
11653  int off_x, float start_point)
11654 {
11655  struct nk_tt__active_edge *z = (struct nk_tt__active_edge *)
11656  nk_tt__hheap_alloc(hh, sizeof(*z));
11657  float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
11658  /*STBTT_assert(e->y0 <= start_point); */
11659  if (!z) return z;
11660  z->fdx = dxdy;
11661  z->fdy = (dxdy != 0) ? (1/dxdy): 0;
11662  z->fx = e->x0 + dxdy * (start_point - e->y0);
11663  z->fx -= (float)off_x;
11664  z->direction = e->invert ? 1.0f : -1.0f;
11665  z->sy = e->y0;
11666  z->ey = e->y1;
11667  z->next = 0;
11668  return z;
11669 }
11670 NK_INTERN void
11671 nk_tt__handle_clipped_edge(float *scanline, int x, struct nk_tt__active_edge *e,
11672  float x0, float y0, float x1, float y1)
11673 {
11674  if (y0 == y1) return;
11675  NK_ASSERT(y0 < y1);
11676  NK_ASSERT(e->sy <= e->ey);
11677  if (y0 > e->ey) return;
11678  if (y1 < e->sy) return;
11679  if (y0 < e->sy) {
11680  x0 += (x1-x0) * (e->sy - y0) / (y1-y0);
11681  y0 = e->sy;
11682  }
11683  if (y1 > e->ey) {
11684  x1 += (x1-x0) * (e->ey - y1) / (y1-y0);
11685  y1 = e->ey;
11686  }
11687 
11688  if (x0 == x) NK_ASSERT(x1 <= x+1);
11689  else if (x0 == x+1) NK_ASSERT(x1 >= x);
11690  else if (x0 <= x) NK_ASSERT(x1 <= x);
11691  else if (x0 >= x+1) NK_ASSERT(x1 >= x+1);
11692  else NK_ASSERT(x1 >= x && x1 <= x+1);
11693 
11694  if (x0 <= x && x1 <= x)
11695  scanline[x] += e->direction * (y1-y0);
11696  else if (x0 >= x+1 && x1 >= x+1);
11697  else {
11698  NK_ASSERT(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1);
11699  /* coverage = 1 - average x position */
11700  scanline[x] += (float)e->direction * (float)(y1-y0) * (1.0f-((x0-(float)x)+(x1-(float)x))/2.0f);
11701  }
11702 }
11703 NK_INTERN void
11704 nk_tt__fill_active_edges_new(float *scanline, float *scanline_fill, int len,
11705  struct nk_tt__active_edge *e, float y_top)
11706 {
11707  float y_bottom = y_top+1;
11708  while (e)
11709  {
11710  /* brute force every pixel */
11711  /* compute intersection points with top & bottom */
11712  NK_ASSERT(e->ey >= y_top);
11713  if (e->fdx == 0) {
11714  float x0 = e->fx;
11715  if (x0 < len) {
11716  if (x0 >= 0) {
11717  nk_tt__handle_clipped_edge(scanline,(int) x0,e, x0,y_top, x0,y_bottom);
11718  nk_tt__handle_clipped_edge(scanline_fill-1,(int) x0+1,e, x0,y_top, x0,y_bottom);
11719  } else {
11720  nk_tt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom);
11721  }
11722  }
11723  } else {
11724  float x0 = e->fx;
11725  float dx = e->fdx;
11726  float xb = x0 + dx;
11727  float x_top, x_bottom;
11728  float y0,y1;
11729  float dy = e->fdy;
11730  NK_ASSERT(e->sy <= y_bottom && e->ey >= y_top);
11731 
11732  /* compute endpoints of line segment clipped to this scanline (if the */
11733  /* line segment starts on this scanline. x0 is the intersection of the */
11734  /* line with y_top, but that may be off the line segment. */
11735  if (e->sy > y_top) {
11736  x_top = x0 + dx * (e->sy - y_top);
11737  y0 = e->sy;
11738  } else {
11739  x_top = x0;
11740  y0 = y_top;
11741  }
11742 
11743  if (e->ey < y_bottom) {
11744  x_bottom = x0 + dx * (e->ey - y_top);
11745  y1 = e->ey;
11746  } else {
11747  x_bottom = xb;
11748  y1 = y_bottom;
11749  }
11750 
11751  if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len)
11752  {
11753  /* from here on, we don't have to range check x values */
11754  if ((int) x_top == (int) x_bottom) {
11755  float height;
11756  /* simple case, only spans one pixel */
11757  int x = (int) x_top;
11758  height = y1 - y0;
11759  NK_ASSERT(x >= 0 && x < len);
11760  scanline[x] += e->direction * (1.0f-(((float)x_top - (float)x) + ((float)x_bottom-(float)x))/2.0f) * (float)height;
11761  scanline_fill[x] += e->direction * (float)height; /* everything right of this pixel is filled */
11762  } else {
11763  int x,x1,x2;
11764  float y_crossing, step, sign, area;
11765  /* covers 2+ pixels */
11766  if (x_top > x_bottom)
11767  {
11768  /* flip scanline vertically; signed area is the same */
11769  float t;
11770  y0 = y_bottom - (y0 - y_top);
11771  y1 = y_bottom - (y1 - y_top);
11772  t = y0; y0 = y1; y1 = t;
11773  t = x_bottom; x_bottom = x_top; x_top = t;
11774  dx = -dx;
11775  dy = -dy;
11776  t = x0; x0 = xb; xb = t;
11777  }
11778 
11779  x1 = (int) x_top;
11780  x2 = (int) x_bottom;
11781  /* compute intersection with y axis at x1+1 */
11782  y_crossing = ((float)x1+1 - (float)x0) * (float)dy + (float)y_top;
11783 
11784  sign = e->direction;
11785  /* area of the rectangle covered from y0..y_crossing */
11786  area = sign * (y_crossing-y0);
11787  /* area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing) */
11788  scanline[x1] += area * (1.0f-((float)((float)x_top - (float)x1)+(float)(x1+1-x1))/2.0f);
11789 
11790  step = sign * dy;
11791  for (x = x1+1; x < x2; ++x) {
11792  scanline[x] += area + step/2;
11793  area += step;
11794  }
11795  y_crossing += (float)dy * (float)(x2 - (x1+1));
11796 
11797  scanline[x2] += area + sign * (1.0f-((float)(x2-x2)+((float)x_bottom-(float)x2))/2.0f) * (y1-y_crossing);
11798  scanline_fill[x2] += sign * (y1-y0);
11799  }
11800  }
11801  else
11802  {
11803  /* if edge goes outside of box we're drawing, we require */
11804  /* clipping logic. since this does not match the intended use */
11805  /* of this library, we use a different, very slow brute */
11806  /* force implementation */
11807  int x;
11808  for (x=0; x < len; ++x)
11809  {
11810  /* cases: */
11811  /* */
11812  /* there can be up to two intersections with the pixel. any intersection */
11813  /* with left or right edges can be handled by splitting into two (or three) */
11814  /* regions. intersections with top & bottom do not necessitate case-wise logic. */
11815  /* */
11816  /* the old way of doing this found the intersections with the left & right edges, */
11817  /* then used some simple logic to produce up to three segments in sorted order */
11818  /* from top-to-bottom. however, this had a problem: if an x edge was epsilon */
11819  /* across the x border, then the corresponding y position might not be distinct */
11820  /* from the other y segment, and it might ignored as an empty segment. to avoid */
11821  /* that, we need to explicitly produce segments based on x positions. */
11822 
11823  /* rename variables to clear pairs */
11824  float ya = y_top;
11825  float x1 = (float) (x);
11826  float x2 = (float) (x+1);
11827  float x3 = xb;
11828  float y3 = y_bottom;
11829  float yb,y2;
11830 
11831  yb = ((float)x - x0) / dx + y_top;
11832  y2 = ((float)x+1 - x0) / dx + y_top;
11833 
11834  if (x0 < x1 && x3 > x2) { /* three segments descending down-right */
11835  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb);
11836  nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x2,y2);
11837  nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
11838  } else if (x3 < x1 && x0 > x2) { /* three segments descending down-left */
11839  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2);
11840  nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x1,yb);
11841  nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3);
11842  } else if (x0 < x1 && x3 > x1) { /* two segments across x, down-right */
11843  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb);
11844  nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3);
11845  } else if (x3 < x1 && x0 > x1) { /* two segments across x, down-left */
11846  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb);
11847  nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3);
11848  } else if (x0 < x2 && x3 > x2) { /* two segments across x+1, down-right */
11849  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2);
11850  nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
11851  } else if (x3 < x2 && x0 > x2) { /* two segments across x+1, down-left */
11852  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2);
11853  nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
11854  } else { /* one segment */
11855  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x3,y3);
11856  }
11857  }
11858  }
11859  }
11860  e = e->next;
11861  }
11862 }
11863 NK_INTERN void
11864 nk_tt__rasterize_sorted_edges(struct nk_tt__bitmap *result, struct nk_tt__edge *e,
11865  int n, int vsubsample, int off_x, int off_y, struct nk_allocator *alloc)
11866 {
11867  /* directly AA rasterize edges w/o supersampling */
11868  struct nk_tt__hheap hh;
11869  struct nk_tt__active_edge *active = 0;
11870  int y,j=0, i;
11871  float scanline_data[129], *scanline, *scanline2;
11872 
11873  NK_UNUSED(vsubsample);
11874  nk_zero_struct(hh);
11875  hh.alloc = *alloc;
11876 
11877  if (result->w > 64)
11878  scanline = (float *) alloc->alloc(alloc->userdata,0, (nk_size)(result->w*2+1) * sizeof(float));
11879  else scanline = scanline_data;
11880 
11881  scanline2 = scanline + result->w;
11882  y = off_y;
11883  e[n].y0 = (float) (off_y + result->h) + 1;
11884 
11885  while (j < result->h)
11886  {
11887  /* find center of pixel for this scanline */
11888  float scan_y_top = (float)y + 0.0f;
11889  float scan_y_bottom = (float)y + 1.0f;
11890  struct nk_tt__active_edge **step = &active;
11891 
11892  NK_MEMSET(scanline , 0, (nk_size)result->w*sizeof(scanline[0]));
11893  NK_MEMSET(scanline2, 0, (nk_size)(result->w+1)*sizeof(scanline[0]));
11894 
11895  /* update all active edges; */
11896  /* remove all active edges that terminate before the top of this scanline */
11897  while (*step) {
11898  struct nk_tt__active_edge * z = *step;
11899  if (z->ey <= scan_y_top) {
11900  *step = z->next; /* delete from list */
11901  NK_ASSERT(z->direction);
11902  z->direction = 0;
11903  nk_tt__hheap_free(&hh, z);
11904  } else {
11905  step = &((*step)->next); /* advance through list */
11906  }
11907  }
11908 
11909  /* insert all edges that start before the bottom of this scanline */
11910  while (e->y0 <= scan_y_bottom) {
11911  if (e->y0 != e->y1) {
11912  struct nk_tt__active_edge *z = nk_tt__new_active(&hh, e, off_x, scan_y_top);
11913  if (z != 0) {
11914  NK_ASSERT(z->ey >= scan_y_top);
11915  /* insert at front */
11916  z->next = active;
11917  active = z;
11918  }
11919  }
11920  ++e;
11921  }
11922 
11923  /* now process all active edges */
11924  if (active)
11925  nk_tt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top);
11926 
11927  {
11928  float sum = 0;
11929  for (i=0; i < result->w; ++i) {
11930  float k;
11931  int m;
11932  sum += scanline2[i];
11933  k = scanline[i] + sum;
11934  k = (float) NK_ABS(k) * 255.0f + 0.5f;
11935  m = (int) k;
11936  if (m > 255) m = 255;
11937  result->pixels[j*result->stride + i] = (unsigned char) m;
11938  }
11939  }
11940  /* advance all the edges */
11941  step = &active;
11942  while (*step) {
11943  struct nk_tt__active_edge *z = *step;
11944  z->fx += z->fdx; /* advance to position for current scanline */
11945  step = &((*step)->next); /* advance through list */
11946  }
11947  ++y;
11948  ++j;
11949  }
11950  nk_tt__hheap_cleanup(&hh);
11951  if (scanline != scanline_data)
11952  alloc->free(alloc->userdata, scanline);
11953 }
11954 NK_INTERN void
11955 nk_tt__sort_edges_ins_sort(struct nk_tt__edge *p, int n)
11956 {
11957  int i,j;
11958  #define NK_TT__COMPARE(a,b) ((a)->y0 < (b)->y0)
11959  for (i=1; i < n; ++i) {
11960  struct nk_tt__edge t = p[i], *a = &t;
11961  j = i;
11962  while (j > 0) {
11963  struct nk_tt__edge *b = &p[j-1];
11964  int c = NK_TT__COMPARE(a,b);
11965  if (!c) break;
11966  p[j] = p[j-1];
11967  --j;
11968  }
11969  if (i != j)
11970  p[j] = t;
11971  }
11972 }
11973 NK_INTERN void
11974 nk_tt__sort_edges_quicksort(struct nk_tt__edge *p, int n)
11975 {
11976  /* threshold for transitioning to insertion sort */
11977  while (n > 12) {
11978  struct nk_tt__edge t;
11979  int c01,c12,c,m,i,j;
11980 
11981  /* compute median of three */
11982  m = n >> 1;
11983  c01 = NK_TT__COMPARE(&p[0],&p[m]);
11984  c12 = NK_TT__COMPARE(&p[m],&p[n-1]);
11985 
11986  /* if 0 >= mid >= end, or 0 < mid < end, then use mid */
11987  if (c01 != c12) {
11988  /* otherwise, we'll need to swap something else to middle */
11989  int z;
11990  c = NK_TT__COMPARE(&p[0],&p[n-1]);
11991  /* 0>mid && mid<n: 0>n => n; 0<n => 0 */
11992  /* 0<mid && mid>n: 0>n => 0; 0<n => n */
11993  z = (c == c12) ? 0 : n-1;
11994  t = p[z];
11995  p[z] = p[m];
11996  p[m] = t;
11997  }
11998 
11999  /* now p[m] is the median-of-three */
12000  /* swap it to the beginning so it won't move around */
12001  t = p[0];
12002  p[0] = p[m];
12003  p[m] = t;
12004 
12005  /* partition loop */
12006  i=1;
12007  j=n-1;
12008  for(;;) {
12009  /* handling of equality is crucial here */
12010  /* for sentinels & efficiency with duplicates */
12011  for (;;++i) {
12012  if (!NK_TT__COMPARE(&p[i], &p[0])) break;
12013  }
12014  for (;;--j) {
12015  if (!NK_TT__COMPARE(&p[0], &p[j])) break;
12016  }
12017 
12018  /* make sure we haven't crossed */
12019  if (i >= j) break;
12020  t = p[i];
12021  p[i] = p[j];
12022  p[j] = t;
12023 
12024  ++i;
12025  --j;
12026 
12027  }
12028 
12029  /* recurse on smaller side, iterate on larger */
12030  if (j < (n-i)) {
12031  nk_tt__sort_edges_quicksort(p,j);
12032  p = p+i;
12033  n = n-i;
12034  } else {
12035  nk_tt__sort_edges_quicksort(p+i, n-i);
12036  n = j;
12037  }
12038  }
12039 }
12040 NK_INTERN void
12041 nk_tt__sort_edges(struct nk_tt__edge *p, int n)
12042 {
12043  nk_tt__sort_edges_quicksort(p, n);
12044  nk_tt__sort_edges_ins_sort(p, n);
12045 }
12046 NK_INTERN void
12047 nk_tt__rasterize(struct nk_tt__bitmap *result, struct nk_tt__point *pts,
12048  int *wcount, int windings, float scale_x, float scale_y,
12049  float shift_x, float shift_y, int off_x, int off_y, int invert,
12050  struct nk_allocator *alloc)
12051 {
12052  float y_scale_inv = invert ? -scale_y : scale_y;
12053  struct nk_tt__edge *e;
12054  int n,i,j,k,m;
12055  int vsubsample = 1;
12056  /* vsubsample should divide 255 evenly; otherwise we won't reach full opacity */
12057 
12058  /* now we have to blow out the windings into explicit edge lists */
12059  n = 0;
12060  for (i=0; i < windings; ++i)
12061  n += wcount[i];
12062 
12063  e = (struct nk_tt__edge*)
12064  alloc->alloc(alloc->userdata, 0,(sizeof(*e) * (nk_size)(n+1)));
12065  if (e == 0) return;
12066  n = 0;
12067 
12068  m=0;
12069  for (i=0; i < windings; ++i)
12070  {
12071  struct nk_tt__point *p = pts + m;
12072  m += wcount[i];
12073  j = wcount[i]-1;
12074  for (k=0; k < wcount[i]; j=k++) {
12075  int a=k,b=j;
12076  /* skip the edge if horizontal */
12077  if (p[j].y == p[k].y)
12078  continue;
12079 
12080  /* add edge from j to k to the list */
12081  e[n].invert = 0;
12082  if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
12083  e[n].invert = 1;
12084  a=j,b=k;
12085  }
12086  e[n].x0 = p[a].x * scale_x + shift_x;
12087  e[n].y0 = (p[a].y * y_scale_inv + shift_y) * (float)vsubsample;
12088  e[n].x1 = p[b].x * scale_x + shift_x;
12089  e[n].y1 = (p[b].y * y_scale_inv + shift_y) * (float)vsubsample;
12090  ++n;
12091  }
12092  }
12093 
12094  /* now sort the edges by their highest point (should snap to integer, and then by x) */
12095  /*STBTT_sort(e, n, sizeof(e[0]), nk_tt__edge_compare); */
12096  nk_tt__sort_edges(e, n);
12097  /* now, traverse the scanlines and find the intersections on each scanline, use xor winding rule */
12098  nk_tt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, alloc);
12099  alloc->free(alloc->userdata, e);
12100 }
12101 NK_INTERN void
12102 nk_tt__add_point(struct nk_tt__point *points, int n, float x, float y)
12103 {
12104  if (!points) return; /* during first pass, it's unallocated */
12105  points[n].x = x;
12106  points[n].y = y;
12107 }
12108 NK_INTERN int
12109 nk_tt__tesselate_curve(struct nk_tt__point *points, int *num_points,
12110  float x0, float y0, float x1, float y1, float x2, float y2,
12111  float objspace_flatness_squared, int n)
12112 {
12113  /* tesselate until threshold p is happy...
12114  * @TODO warped to compensate for non-linear stretching */
12115  /* midpoint */
12116  float mx = (x0 + 2*x1 + x2)/4;
12117  float my = (y0 + 2*y1 + y2)/4;
12118  /* versus directly drawn line */
12119  float dx = (x0+x2)/2 - mx;
12120  float dy = (y0+y2)/2 - my;
12121  if (n > 16) /* 65536 segments on one curve better be enough! */
12122  return 1;
12123 
12124  /* half-pixel error allowed... need to be smaller if AA */
12125  if (dx*dx+dy*dy > objspace_flatness_squared) {
12126  nk_tt__tesselate_curve(points, num_points, x0,y0,
12127  (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1);
12128  nk_tt__tesselate_curve(points, num_points, mx,my,
12129  (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1);
12130  } else {
12131  nk_tt__add_point(points, *num_points,x2,y2);
12132  *num_points = *num_points+1;
12133  }
12134  return 1;
12135 }
12136 NK_INTERN struct nk_tt__point*
12137 nk_tt_FlattenCurves(struct nk_tt_vertex *vertices, int num_verts,
12138  float objspace_flatness, int **contour_lengths, int *num_contours,
12139  struct nk_allocator *alloc)
12140 {
12141  /* returns number of contours */
12142  struct nk_tt__point *points=0;
12143  int num_points=0;
12144  float objspace_flatness_squared = objspace_flatness * objspace_flatness;
12145  int i;
12146  int n=0;
12147  int start=0;
12148  int pass;
12149 
12150  /* count how many "moves" there are to get the contour count */
12151  for (i=0; i < num_verts; ++i)
12152  if (vertices[i].type == NK_TT_vmove) ++n;
12153 
12154  *num_contours = n;
12155  if (n == 0) return 0;
12156 
12157  *contour_lengths = (int *)
12158  alloc->alloc(alloc->userdata,0, (sizeof(**contour_lengths) * (nk_size)n));
12159  if (*contour_lengths == 0) {
12160  *num_contours = 0;
12161  return 0;
12162  }
12163 
12164  /* make two passes through the points so we don't need to realloc */
12165  for (pass=0; pass < 2; ++pass)
12166  {
12167  float x=0,y=0;
12168  if (pass == 1) {
12169  points = (struct nk_tt__point *)
12170  alloc->alloc(alloc->userdata,0, (nk_size)num_points * sizeof(points[0]));
12171  if (points == 0) goto error;
12172  }
12173  num_points = 0;
12174  n= -1;
12175 
12176  for (i=0; i < num_verts; ++i)
12177  {
12178  switch (vertices[i].type) {
12179  case NK_TT_vmove:
12180  /* start the next contour */
12181  if (n >= 0)
12182  (*contour_lengths)[n] = num_points - start;
12183  ++n;
12184  start = num_points;
12185 
12186  x = vertices[i].x, y = vertices[i].y;
12187  nk_tt__add_point(points, num_points++, x,y);
12188  break;
12189  case NK_TT_vline:
12190  x = vertices[i].x, y = vertices[i].y;
12191  nk_tt__add_point(points, num_points++, x, y);
12192  break;
12193  case NK_TT_vcurve:
12194  nk_tt__tesselate_curve(points, &num_points, x,y,
12195  vertices[i].cx, vertices[i].cy,
12196  vertices[i].x, vertices[i].y,
12197  objspace_flatness_squared, 0);
12198  x = vertices[i].x, y = vertices[i].y;
12199  break;
12200  default: break;
12201  }
12202  }
12203  (*contour_lengths)[n] = num_points - start;
12204  }
12205  return points;
12206 
12207 error:
12208  alloc->free(alloc->userdata, points);
12209  alloc->free(alloc->userdata, *contour_lengths);
12210  *contour_lengths = 0;
12211  *num_contours = 0;
12212  return 0;
12213 }
12214 NK_INTERN void
12215 nk_tt_Rasterize(struct nk_tt__bitmap *result, float flatness_in_pixels,
12216  struct nk_tt_vertex *vertices, int num_verts,
12217  float scale_x, float scale_y, float shift_x, float shift_y,
12218  int x_off, int y_off, int invert, struct nk_allocator *alloc)
12219 {
12220  float scale = scale_x > scale_y ? scale_y : scale_x;
12221  int winding_count, *winding_lengths;
12222  struct nk_tt__point *windings = nk_tt_FlattenCurves(vertices, num_verts,
12223  flatness_in_pixels / scale, &winding_lengths, &winding_count, alloc);
12224 
12225  NK_ASSERT(alloc);
12226  if (windings) {
12227  nk_tt__rasterize(result, windings, winding_lengths, winding_count,
12228  scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, alloc);
12229  alloc->free(alloc->userdata, winding_lengths);
12230  alloc->free(alloc->userdata, windings);
12231  }
12232 }
12233 NK_INTERN void
12234 nk_tt_MakeGlyphBitmapSubpixel(const struct nk_tt_fontinfo *info, unsigned char *output,
12235  int out_w, int out_h, int out_stride, float scale_x, float scale_y,
12236  float shift_x, float shift_y, int glyph, struct nk_allocator *alloc)
12237 {
12238  int ix0,iy0;
12239  struct nk_tt_vertex *vertices;
12240  int num_verts = nk_tt_GetGlyphShape(info, alloc, glyph, &vertices);
12241  struct nk_tt__bitmap gbm;
12242 
12243  nk_tt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x,
12244  shift_y, &ix0,&iy0,0,0);
12245  gbm.pixels = output;
12246  gbm.w = out_w;
12247  gbm.h = out_h;
12248  gbm.stride = out_stride;
12249 
12250  if (gbm.w && gbm.h)
12251  nk_tt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y,
12252  shift_x, shift_y, ix0,iy0, 1, alloc);
12253  alloc->free(alloc->userdata, vertices);
12254 }
12255 
12256 /*-------------------------------------------------------------
12257  * Bitmap baking
12258  * --------------------------------------------------------------*/
12259 NK_INTERN int
12260 nk_tt_PackBegin(struct nk_tt_pack_context *spc, unsigned char *pixels,
12261  int pw, int ph, int stride_in_bytes, int padding, struct nk_allocator *alloc)
12262 {
12263  int num_nodes = pw - padding;
12264  struct nk_rp_context *context = (struct nk_rp_context *)
12265  alloc->alloc(alloc->userdata,0, sizeof(*context));
12266  struct nk_rp_node *nodes = (struct nk_rp_node*)
12267  alloc->alloc(alloc->userdata,0, (sizeof(*nodes ) * (nk_size)num_nodes));
12268 
12269  if (context == 0 || nodes == 0) {
12270  if (context != 0) alloc->free(alloc->userdata, context);
12271  if (nodes != 0) alloc->free(alloc->userdata, nodes);
12272  return 0;
12273  }
12274 
12275  spc->width = pw;
12276  spc->height = ph;
12277  spc->pixels = pixels;
12278  spc->pack_info = context;
12279  spc->nodes = nodes;
12280  spc->padding = padding;
12281  spc->stride_in_bytes = (stride_in_bytes != 0) ? stride_in_bytes : pw;
12282  spc->h_oversample = 1;
12283  spc->v_oversample = 1;
12284 
12285  nk_rp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
12286  if (pixels)
12287  NK_MEMSET(pixels, 0, (nk_size)(pw*ph)); /* background of 0 around pixels */
12288  return 1;
12289 }
12290 NK_INTERN void
12291 nk_tt_PackEnd(struct nk_tt_pack_context *spc, struct nk_allocator *alloc)
12292 {
12293  alloc->free(alloc->userdata, spc->nodes);
12294  alloc->free(alloc->userdata, spc->pack_info);
12295 }
12296 NK_INTERN void
12297 nk_tt_PackSetOversampling(struct nk_tt_pack_context *spc,
12298  unsigned int h_oversample, unsigned int v_oversample)
12299 {
12300  NK_ASSERT(h_oversample <= NK_TT_MAX_OVERSAMPLE);
12301  NK_ASSERT(v_oversample <= NK_TT_MAX_OVERSAMPLE);
12302  if (h_oversample <= NK_TT_MAX_OVERSAMPLE)
12303  spc->h_oversample = h_oversample;
12304  if (v_oversample <= NK_TT_MAX_OVERSAMPLE)
12305  spc->v_oversample = v_oversample;
12306 }
12307 NK_INTERN void
12308 nk_tt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes,
12309  int kernel_width)
12310 {
12311  unsigned char buffer[NK_TT_MAX_OVERSAMPLE];
12312  int safe_w = w - kernel_width;
12313  int j;
12314 
12315  for (j=0; j < h; ++j)
12316  {
12317  int i;
12318  unsigned int total;
12319  NK_MEMSET(buffer, 0, (nk_size)kernel_width);
12320 
12321  total = 0;
12322 
12323  /* make kernel_width a constant in common cases so compiler can optimize out the divide */
12324  switch (kernel_width) {
12325  case 2:
12326  for (i=0; i <= safe_w; ++i) {
12327  total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
12328  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12329  pixels[i] = (unsigned char) (total / 2);
12330  }
12331  break;
12332  case 3:
12333  for (i=0; i <= safe_w; ++i) {
12334  total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
12335  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12336  pixels[i] = (unsigned char) (total / 3);
12337  }
12338  break;
12339  case 4:
12340  for (i=0; i <= safe_w; ++i) {
12341  total += (unsigned int)pixels[i] - buffer[i & NK_TT__OVER_MASK];
12342  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12343  pixels[i] = (unsigned char) (total / 4);
12344  }
12345  break;
12346  case 5:
12347  for (i=0; i <= safe_w; ++i) {
12348  total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
12349  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12350  pixels[i] = (unsigned char) (total / 5);
12351  }
12352  break;
12353  default:
12354  for (i=0; i <= safe_w; ++i) {
12355  total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
12356  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12357  pixels[i] = (unsigned char) (total / (unsigned int)kernel_width);
12358  }
12359  break;
12360  }
12361 
12362  for (; i < w; ++i) {
12363  NK_ASSERT(pixels[i] == 0);
12364  total -= (unsigned int)(buffer[i & NK_TT__OVER_MASK]);
12365  pixels[i] = (unsigned char) (total / (unsigned int)kernel_width);
12366  }
12367  pixels += stride_in_bytes;
12368  }
12369 }
12370 NK_INTERN void
12371 nk_tt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes,
12372  int kernel_width)
12373 {
12374  unsigned char buffer[NK_TT_MAX_OVERSAMPLE];
12375  int safe_h = h - kernel_width;
12376  int j;
12377 
12378  for (j=0; j < w; ++j)
12379  {
12380  int i;
12381  unsigned int total;
12382  NK_MEMSET(buffer, 0, (nk_size)kernel_width);
12383 
12384  total = 0;
12385 
12386  /* make kernel_width a constant in common cases so compiler can optimize out the divide */
12387  switch (kernel_width) {
12388  case 2:
12389  for (i=0; i <= safe_h; ++i) {
12390  total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12391  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12392  pixels[i*stride_in_bytes] = (unsigned char) (total / 2);
12393  }
12394  break;
12395  case 3:
12396  for (i=0; i <= safe_h; ++i) {
12397  total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12398  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12399  pixels[i*stride_in_bytes] = (unsigned char) (total / 3);
12400  }
12401  break;
12402  case 4:
12403  for (i=0; i <= safe_h; ++i) {
12404  total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12405  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12406  pixels[i*stride_in_bytes] = (unsigned char) (total / 4);
12407  }
12408  break;
12409  case 5:
12410  for (i=0; i <= safe_h; ++i) {
12411  total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12412  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12413  pixels[i*stride_in_bytes] = (unsigned char) (total / 5);
12414  }
12415  break;
12416  default:
12417  for (i=0; i <= safe_h; ++i) {
12418  total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12419  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12420  pixels[i*stride_in_bytes] = (unsigned char) (total / (unsigned int)kernel_width);
12421  }
12422  break;
12423  }
12424 
12425  for (; i < h; ++i) {
12426  NK_ASSERT(pixels[i*stride_in_bytes] == 0);
12427  total -= (unsigned int)(buffer[i & NK_TT__OVER_MASK]);
12428  pixels[i*stride_in_bytes] = (unsigned char) (total / (unsigned int)kernel_width);
12429  }
12430  pixels += 1;
12431  }
12432 }
12433 NK_INTERN float
12434 nk_tt__oversample_shift(int oversample)
12435 {
12436  if (!oversample)
12437  return 0.0f;
12438 
12439  /* The prefilter is a box filter of width "oversample", */
12440  /* which shifts phase by (oversample - 1)/2 pixels in */
12441  /* oversampled space. We want to shift in the opposite */
12442  /* direction to counter this. */
12443  return (float)-(oversample - 1) / (2.0f * (float)oversample);
12444 }
12445 NK_INTERN int
12446 nk_tt_PackFontRangesGatherRects(struct nk_tt_pack_context *spc,
12447  struct nk_tt_fontinfo *info, struct nk_tt_pack_range *ranges,
12448  int num_ranges, struct nk_rp_rect *rects)
12449 {
12450  /* rects array must be big enough to accommodate all characters in the given ranges */
12451  int i,j,k;
12452  k = 0;
12453 
12454  for (i=0; i < num_ranges; ++i) {
12455  float fh = ranges[i].font_size;
12456  float scale = (fh > 0) ? nk_tt_ScaleForPixelHeight(info, fh):
12457  nk_tt_ScaleForMappingEmToPixels(info, -fh);
12458  ranges[i].h_oversample = (unsigned char) spc->h_oversample;
12459  ranges[i].v_oversample = (unsigned char) spc->v_oversample;
12460  for (j=0; j < ranges[i].num_chars; ++j) {
12461  int x0,y0,x1,y1;
12462  int codepoint = ranges[i].first_unicode_codepoint_in_range ?
12463  ranges[i].first_unicode_codepoint_in_range + j :
12464  ranges[i].array_of_unicode_codepoints[j];
12465 
12466  int glyph = nk_tt_FindGlyphIndex(info, codepoint);
12467  nk_tt_GetGlyphBitmapBoxSubpixel(info,glyph, scale * (float)spc->h_oversample,
12468  scale * (float)spc->v_oversample, 0,0, &x0,&y0,&x1,&y1);
12469  rects[k].w = (nk_rp_coord) (x1-x0 + spc->padding + (int)spc->h_oversample-1);
12470  rects[k].h = (nk_rp_coord) (y1-y0 + spc->padding + (int)spc->v_oversample-1);
12471  ++k;
12472  }
12473  }
12474  return k;
12475 }
12476 NK_INTERN int
12477 nk_tt_PackFontRangesRenderIntoRects(struct nk_tt_pack_context *spc,
12478  struct nk_tt_fontinfo *info, struct nk_tt_pack_range *ranges,
12479  int num_ranges, struct nk_rp_rect *rects, struct nk_allocator *alloc)
12480 {
12481  int i,j,k, return_value = 1;
12482  /* save current values */
12483  int old_h_over = (int)spc->h_oversample;
12484  int old_v_over = (int)spc->v_oversample;
12485  /* rects array must be big enough to accommodate all characters in the given ranges */
12486 
12487  k = 0;
12488  for (i=0; i < num_ranges; ++i)
12489  {
12490  float fh = ranges[i].font_size;
12491  float recip_h,recip_v,sub_x,sub_y;
12492  float scale = fh > 0 ? nk_tt_ScaleForPixelHeight(info, fh):
12493  nk_tt_ScaleForMappingEmToPixels(info, -fh);
12494 
12495  spc->h_oversample = ranges[i].h_oversample;
12496  spc->v_oversample = ranges[i].v_oversample;
12497 
12498  recip_h = 1.0f / (float)spc->h_oversample;
12499  recip_v = 1.0f / (float)spc->v_oversample;
12500 
12501  sub_x = nk_tt__oversample_shift((int)spc->h_oversample);
12502  sub_y = nk_tt__oversample_shift((int)spc->v_oversample);
12503 
12504  for (j=0; j < ranges[i].num_chars; ++j)
12505  {
12506  struct nk_rp_rect *r = &rects[k];
12507  if (r->was_packed)
12508  {
12509  struct nk_tt_packedchar *bc = &ranges[i].chardata_for_range[j];
12510  int advance, lsb, x0,y0,x1,y1;
12511  int codepoint = ranges[i].first_unicode_codepoint_in_range ?
12512  ranges[i].first_unicode_codepoint_in_range + j :
12513  ranges[i].array_of_unicode_codepoints[j];
12514  int glyph = nk_tt_FindGlyphIndex(info, codepoint);
12515  nk_rp_coord pad = (nk_rp_coord) spc->padding;
12516 
12517  /* pad on left and top */
12518  r->x = (nk_rp_coord)((int)r->x + (int)pad);
12519  r->y = (nk_rp_coord)((int)r->y + (int)pad);
12520  r->w = (nk_rp_coord)((int)r->w - (int)pad);
12521  r->h = (nk_rp_coord)((int)r->h - (int)pad);
12522 
12523  nk_tt_GetGlyphHMetrics(info, glyph, &advance, &lsb);
12524  nk_tt_GetGlyphBitmapBox(info, glyph, scale * (float)spc->h_oversample,
12525  (scale * (float)spc->v_oversample), &x0,&y0,&x1,&y1);
12526  nk_tt_MakeGlyphBitmapSubpixel(info, spc->pixels + r->x + r->y*spc->stride_in_bytes,
12527  (int)(r->w - spc->h_oversample+1), (int)(r->h - spc->v_oversample+1),
12528  spc->stride_in_bytes, scale * (float)spc->h_oversample,
12529  scale * (float)spc->v_oversample, 0,0, glyph, alloc);
12530 
12531  if (spc->h_oversample > 1)
12532  nk_tt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
12533  r->w, r->h, spc->stride_in_bytes, (int)spc->h_oversample);
12534 
12535  if (spc->v_oversample > 1)
12536  nk_tt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
12537  r->w, r->h, spc->stride_in_bytes, (int)spc->v_oversample);
12538 
12539  bc->x0 = (nk_ushort) r->x;
12540  bc->y0 = (nk_ushort) r->y;
12541  bc->x1 = (nk_ushort) (r->x + r->w);
12542  bc->y1 = (nk_ushort) (r->y + r->h);
12543  bc->xadvance = scale * (float)advance;
12544  bc->xoff = (float) x0 * recip_h + sub_x;
12545  bc->yoff = (float) y0 * recip_v + sub_y;
12546  bc->xoff2 = ((float)x0 + r->w) * recip_h + sub_x;
12547  bc->yoff2 = ((float)y0 + r->h) * recip_v + sub_y;
12548  } else {
12549  return_value = 0; /* if any fail, report failure */
12550  }
12551  ++k;
12552  }
12553  }
12554  /* restore original values */
12555  spc->h_oversample = (unsigned int)old_h_over;
12556  spc->v_oversample = (unsigned int)old_v_over;
12557  return return_value;
12558 }
12559 NK_INTERN void
12560 nk_tt_GetPackedQuad(struct nk_tt_packedchar *chardata, int pw, int ph,
12561  int char_index, float *xpos, float *ypos, struct nk_tt_aligned_quad *q,
12562  int align_to_integer)
12563 {
12564  float ipw = 1.0f / (float)pw, iph = 1.0f / (float)ph;
12565  struct nk_tt_packedchar *b = (struct nk_tt_packedchar*)(chardata + char_index);
12566  if (align_to_integer) {
12567  int tx = nk_ifloorf((*xpos + b->xoff) + 0.5f);
12568  int ty = nk_ifloorf((*ypos + b->yoff) + 0.5f);
12569 
12570  float x = (float)tx;
12571  float y = (float)ty;
12572 
12573  q->x0 = x;
12574  q->y0 = y;
12575  q->x1 = x + b->xoff2 - b->xoff;
12576  q->y1 = y + b->yoff2 - b->yoff;
12577  } else {
12578  q->x0 = *xpos + b->xoff;
12579  q->y0 = *ypos + b->yoff;
12580  q->x1 = *xpos + b->xoff2;
12581  q->y1 = *ypos + b->yoff2;
12582  }
12583  q->s0 = b->x0 * ipw;
12584  q->t0 = b->y0 * iph;
12585  q->s1 = b->x1 * ipw;
12586  q->t1 = b->y1 * iph;
12587  *xpos += b->xadvance;
12588 }
12589 
12590 /* -------------------------------------------------------------
12591  *
12592  * FONT BAKING
12593  *
12594  * --------------------------------------------------------------*/
12595 struct nk_font_bake_data {
12596  struct nk_tt_fontinfo info;
12597  struct nk_rp_rect *rects;
12598  struct nk_tt_pack_range *ranges;
12599  nk_rune range_count;
12600 };
12601 
12602 struct nk_font_baker {
12603  struct nk_allocator alloc;
12604  struct nk_tt_pack_context spc;
12605  struct nk_font_bake_data *build;
12606  struct nk_tt_packedchar *packed_chars;
12607  struct nk_rp_rect *rects;
12608  struct nk_tt_pack_range *ranges;
12609 };
12610 
12611 NK_GLOBAL const nk_size nk_rect_align = NK_ALIGNOF(struct nk_rp_rect);
12612 NK_GLOBAL const nk_size nk_range_align = NK_ALIGNOF(struct nk_tt_pack_range);
12613 NK_GLOBAL const nk_size nk_char_align = NK_ALIGNOF(struct nk_tt_packedchar);
12614 NK_GLOBAL const nk_size nk_build_align = NK_ALIGNOF(struct nk_font_bake_data);
12615 NK_GLOBAL const nk_size nk_baker_align = NK_ALIGNOF(struct nk_font_baker);
12616 
12617 NK_INTERN int
12618 nk_range_count(const nk_rune *range)
12619 {
12620  const nk_rune *iter = range;
12621  NK_ASSERT(range);
12622  if (!range) return 0;
12623  while (*(iter++) != 0);
12624  return (iter == range) ? 0 : (int)((iter - range)/2);
12625 }
12626 NK_INTERN int
12627 nk_range_glyph_count(const nk_rune *range, int count)
12628 {
12629  int i = 0;
12630  int total_glyphs = 0;
12631  for (i = 0; i < count; ++i) {
12632  int diff;
12633  nk_rune f = range[(i*2)+0];
12634  nk_rune t = range[(i*2)+1];
12635  NK_ASSERT(t >= f);
12636  diff = (int)((t - f) + 1);
12637  total_glyphs += diff;
12638  }
12639  return total_glyphs;
12640 }
12641 NK_API const nk_rune*
12642 nk_font_default_glyph_ranges(void)
12643 {
12644  NK_STORAGE const nk_rune ranges[] = {0x0020, 0x00FF, 0};
12645  return ranges;
12646 }
12647 NK_API const nk_rune*
12648 nk_font_chinese_glyph_ranges(void)
12649 {
12650  NK_STORAGE const nk_rune ranges[] = {
12651  0x0020, 0x00FF,
12652  0x3000, 0x30FF,
12653  0x31F0, 0x31FF,
12654  0xFF00, 0xFFEF,
12655  0x4e00, 0x9FAF,
12656  0
12657  };
12658  return ranges;
12659 }
12660 NK_API const nk_rune*
12661 nk_font_cyrillic_glyph_ranges(void)
12662 {
12663  NK_STORAGE const nk_rune ranges[] = {
12664  0x0020, 0x00FF,
12665  0x0400, 0x052F,
12666  0x2DE0, 0x2DFF,
12667  0xA640, 0xA69F,
12668  0
12669  };
12670  return ranges;
12671 }
12672 NK_API const nk_rune*
12673 nk_font_korean_glyph_ranges(void)
12674 {
12675  NK_STORAGE const nk_rune ranges[] = {
12676  0x0020, 0x00FF,
12677  0x3131, 0x3163,
12678  0xAC00, 0xD79D,
12679  0
12680  };
12681  return ranges;
12682 }
12683 NK_INTERN void
12684 nk_font_baker_memory(nk_size *temp, int *glyph_count,
12685  struct nk_font_config *config_list, int count)
12686 {
12687  int range_count = 0;
12688  int total_range_count = 0;
12689  struct nk_font_config *iter, *i;
12690 
12691  NK_ASSERT(config_list);
12692  NK_ASSERT(glyph_count);
12693  if (!config_list) {
12694  *temp = 0;
12695  *glyph_count = 0;
12696  return;
12697  }
12698  *glyph_count = 0;
12699  for (iter = config_list; iter; iter = iter->next) {
12700  i = iter;
12701  do {if (!i->range) iter->range = nk_font_default_glyph_ranges();
12702  range_count = nk_range_count(i->range);
12703  total_range_count += range_count;
12704  *glyph_count += nk_range_glyph_count(i->range, range_count);
12705  } while ((i = i->n) != iter);
12706  }
12707  *temp = (nk_size)*glyph_count * sizeof(struct nk_rp_rect);
12708  *temp += (nk_size)total_range_count * sizeof(struct nk_tt_pack_range);
12709  *temp += (nk_size)*glyph_count * sizeof(struct nk_tt_packedchar);
12710  *temp += (nk_size)count * sizeof(struct nk_font_bake_data);
12711  *temp += sizeof(struct nk_font_baker);
12712  *temp += nk_rect_align + nk_range_align + nk_char_align;
12713  *temp += nk_build_align + nk_baker_align;
12714 }
12715 NK_INTERN struct nk_font_baker*
12716 nk_font_baker(void *memory, int glyph_count, int count, struct nk_allocator *alloc)
12717 {
12718  struct nk_font_baker *baker;
12719  if (!memory) return 0;
12720  /* setup baker inside a memory block */
12721  baker = (struct nk_font_baker*)NK_ALIGN_PTR(memory, nk_baker_align);
12722  baker->build = (struct nk_font_bake_data*)NK_ALIGN_PTR((baker + 1), nk_build_align);
12723  baker->packed_chars = (struct nk_tt_packedchar*)NK_ALIGN_PTR((baker->build + count), nk_char_align);
12724  baker->rects = (struct nk_rp_rect*)NK_ALIGN_PTR((baker->packed_chars + glyph_count), nk_rect_align);
12725  baker->ranges = (struct nk_tt_pack_range*)NK_ALIGN_PTR((baker->rects + glyph_count), nk_range_align);
12726  baker->alloc = *alloc;
12727  return baker;
12728 }
12729 NK_INTERN int
12730 nk_font_bake_pack(struct nk_font_baker *baker,
12731  nk_size *image_memory, int *width, int *height, struct nk_recti *custom,
12732  const struct nk_font_config *config_list, int count,
12733  struct nk_allocator *alloc)
12734 {
12735  NK_STORAGE const nk_size max_height = 1024 * 32;
12736  const struct nk_font_config *config_iter, *it;
12737  int total_glyph_count = 0;
12738  int total_range_count = 0;
12739  int range_count = 0;
12740  int i = 0;
12741 
12742  NK_ASSERT(image_memory);
12743  NK_ASSERT(width);
12744  NK_ASSERT(height);
12745  NK_ASSERT(config_list);
12746  NK_ASSERT(count);
12747  NK_ASSERT(alloc);
12748 
12749  if (!image_memory || !width || !height || !config_list || !count) return nk_false;
12750  for (config_iter = config_list; config_iter; config_iter = config_iter->next) {
12751  it = config_iter;
12752  do {range_count = nk_range_count(it->range);
12753  total_range_count += range_count;
12754  total_glyph_count += nk_range_glyph_count(it->range, range_count);
12755  } while ((it = it->n) != config_iter);
12756  }
12757  /* setup font baker from temporary memory */
12758  for (config_iter = config_list; config_iter; config_iter = config_iter->next) {
12759  it = config_iter;
12760  do {if (!nk_tt_InitFont(&baker->build[i++].info, (const unsigned char*)it->ttf_blob, 0))
12761  return nk_false;
12762  } while ((it = it->n) != config_iter);
12763  }
12764  *height = 0;
12765  *width = (total_glyph_count > 1000) ? 1024 : 512;
12766  nk_tt_PackBegin(&baker->spc, 0, (int)*width, (int)max_height, 0, 1, alloc);
12767  {
12768  int input_i = 0;
12769  int range_n = 0;
12770  int rect_n = 0;
12771  int char_n = 0;
12772 
12773  if (custom) {
12774  /* pack custom user data first so it will be in the upper left corner*/
12775  struct nk_rp_rect custom_space;
12776  nk_zero(&custom_space, sizeof(custom_space));
12777  custom_space.w = (nk_rp_coord)(custom->w);
12778  custom_space.h = (nk_rp_coord)(custom->h);
12779 
12780  nk_tt_PackSetOversampling(&baker->spc, 1, 1);
12781  nk_rp_pack_rects((struct nk_rp_context*)baker->spc.pack_info, &custom_space, 1);
12782  *height = NK_MAX(*height, (int)(custom_space.y + custom_space.h));
12783 
12784  custom->x = (short)custom_space.x;
12785  custom->y = (short)custom_space.y;
12786  custom->w = (short)custom_space.w;
12787  custom->h = (short)custom_space.h;
12788  }
12789 
12790  /* first font pass: pack all glyphs */
12791  for (input_i = 0, config_iter = config_list; input_i < count && config_iter;
12792  config_iter = config_iter->next) {
12793  it = config_iter;
12794  do {int n = 0;
12795  int glyph_count;
12796  const nk_rune *in_range;
12797  const struct nk_font_config *cfg = it;
12798  struct nk_font_bake_data *tmp = &baker->build[input_i++];
12799 
12800  /* count glyphs + ranges in current font */
12801  glyph_count = 0; range_count = 0;
12802  for (in_range = cfg->range; in_range[0] && in_range[1]; in_range += 2) {
12803  glyph_count += (int)(in_range[1] - in_range[0]) + 1;
12804  range_count++;
12805  }
12806 
12807  /* setup ranges */
12808  tmp->ranges = baker->ranges + range_n;
12809  tmp->range_count = (nk_rune)range_count;
12810  range_n += range_count;
12811  for (i = 0; i < range_count; ++i) {
12812  in_range = &cfg->range[i * 2];
12813  tmp->ranges[i].font_size = cfg->size;
12814  tmp->ranges[i].first_unicode_codepoint_in_range = (int)in_range[0];
12815  tmp->ranges[i].num_chars = (int)(in_range[1]- in_range[0]) + 1;
12816  tmp->ranges[i].chardata_for_range = baker->packed_chars + char_n;
12817  char_n += tmp->ranges[i].num_chars;
12818  }
12819 
12820  /* pack */
12821  tmp->rects = baker->rects + rect_n;
12822  rect_n += glyph_count;
12823  nk_tt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
12824  n = nk_tt_PackFontRangesGatherRects(&baker->spc, &tmp->info,
12825  tmp->ranges, (int)tmp->range_count, tmp->rects);
12826  nk_rp_pack_rects((struct nk_rp_context*)baker->spc.pack_info, tmp->rects, (int)n);
12827 
12828  /* texture height */
12829  for (i = 0; i < n; ++i) {
12830  if (tmp->rects[i].was_packed)
12831  *height = NK_MAX(*height, tmp->rects[i].y + tmp->rects[i].h);
12832  }
12833  } while ((it = it->n) != config_iter);
12834  }
12835  NK_ASSERT(rect_n == total_glyph_count);
12836  NK_ASSERT(char_n == total_glyph_count);
12837  NK_ASSERT(range_n == total_range_count);
12838  }
12839  *height = (int)nk_round_up_pow2((nk_uint)*height);
12840  *image_memory = (nk_size)(*width) * (nk_size)(*height);
12841  return nk_true;
12842 }
12843 NK_INTERN void
12844 nk_font_bake(struct nk_font_baker *baker, void *image_memory, int width, int height,
12845  struct nk_font_glyph *glyphs, int glyphs_count,
12846  const struct nk_font_config *config_list, int font_count)
12847 {
12848  int input_i = 0;
12849  nk_rune glyph_n = 0;
12850  const struct nk_font_config *config_iter;
12851  const struct nk_font_config *it;
12852 
12853  NK_ASSERT(image_memory);
12854  NK_ASSERT(width);
12855  NK_ASSERT(height);
12856  NK_ASSERT(config_list);
12857  NK_ASSERT(baker);
12858  NK_ASSERT(font_count);
12859  NK_ASSERT(glyphs_count);
12860  if (!image_memory || !width || !height || !config_list ||
12861  !font_count || !glyphs || !glyphs_count)
12862  return;
12863 
12864  /* second font pass: render glyphs */
12865  nk_zero(image_memory, (nk_size)((nk_size)width * (nk_size)height));
12866  baker->spc.pixels = (unsigned char*)image_memory;
12867  baker->spc.height = (int)height;
12868  for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter;
12869  config_iter = config_iter->next) {
12870  it = config_iter;
12871  do {const struct nk_font_config *cfg = it;
12872  struct nk_font_bake_data *tmp = &baker->build[input_i++];
12873  nk_tt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
12874  nk_tt_PackFontRangesRenderIntoRects(&baker->spc, &tmp->info, tmp->ranges,
12875  (int)tmp->range_count, tmp->rects, &baker->alloc);
12876  } while ((it = it->n) != config_iter);
12877  } nk_tt_PackEnd(&baker->spc, &baker->alloc);
12878 
12879  /* third pass: setup font and glyphs */
12880  for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter;
12881  config_iter = config_iter->next) {
12882  it = config_iter;
12883  do {nk_size i = 0;
12884  int char_idx = 0;
12885  nk_rune glyph_count = 0;
12886  const struct nk_font_config *cfg = it;
12887  struct nk_font_bake_data *tmp = &baker->build[input_i++];
12888  struct nk_baked_font *dst_font = cfg->font;
12889 
12890  float font_scale = nk_tt_ScaleForPixelHeight(&tmp->info, cfg->size);
12891  int unscaled_ascent, unscaled_descent, unscaled_line_gap;
12892  nk_tt_GetFontVMetrics(&tmp->info, &unscaled_ascent, &unscaled_descent,
12893  &unscaled_line_gap);
12894 
12895  /* fill baked font */
12896  if (!cfg->merge_mode) {
12897  dst_font->ranges = cfg->range;
12898  dst_font->height = cfg->size;
12899  dst_font->ascent = ((float)unscaled_ascent * font_scale);
12900  dst_font->descent = ((float)unscaled_descent * font_scale);
12901  dst_font->glyph_offset = glyph_n;
12902  // Need to zero this, or it will carry over from a previous
12903  // bake, and cause a segfault when accessing glyphs[].
12904  dst_font->glyph_count = 0;
12905  }
12906 
12907  /* fill own baked font glyph array */
12908  for (i = 0; i < tmp->range_count; ++i) {
12909  struct nk_tt_pack_range *range = &tmp->ranges[i];
12910  for (char_idx = 0; char_idx < range->num_chars; char_idx++)
12911  {
12912  nk_rune codepoint = 0;
12913  float dummy_x = 0, dummy_y = 0;
12914  struct nk_tt_aligned_quad q;
12915  struct nk_font_glyph *glyph;
12916 
12917  /* query glyph bounds from stb_truetype */
12918  const struct nk_tt_packedchar *pc = &range->chardata_for_range[char_idx];
12919  if (!pc->x0 && !pc->x1 && !pc->y0 && !pc->y1) continue;
12920  codepoint = (nk_rune)(range->first_unicode_codepoint_in_range + char_idx);
12921  nk_tt_GetPackedQuad(range->chardata_for_range, (int)width,
12922  (int)height, char_idx, &dummy_x, &dummy_y, &q, 0);
12923 
12924  /* fill own glyph type with data */
12925  glyph = &glyphs[dst_font->glyph_offset + dst_font->glyph_count + (unsigned int)glyph_count];
12926  glyph->codepoint = codepoint;
12927  glyph->x0 = q.x0; glyph->y0 = q.y0;
12928  glyph->x1 = q.x1; glyph->y1 = q.y1;
12929  glyph->y0 += (dst_font->ascent + 0.5f);
12930  glyph->y1 += (dst_font->ascent + 0.5f);
12931  glyph->w = glyph->x1 - glyph->x0 + 0.5f;
12932  glyph->h = glyph->y1 - glyph->y0;
12933 
12934  if (cfg->coord_type == NK_COORD_PIXEL) {
12935  glyph->u0 = q.s0 * (float)width;
12936  glyph->v0 = q.t0 * (float)height;
12937  glyph->u1 = q.s1 * (float)width;
12938  glyph->v1 = q.t1 * (float)height;
12939  } else {
12940  glyph->u0 = q.s0;
12941  glyph->v0 = q.t0;
12942  glyph->u1 = q.s1;
12943  glyph->v1 = q.t1;
12944  }
12945  glyph->xadvance = (pc->xadvance + cfg->spacing.x);
12946  if (cfg->pixel_snap)
12947  glyph->xadvance = (float)(int)(glyph->xadvance + 0.5f);
12948  glyph_count++;
12949  }
12950  }
12951  dst_font->glyph_count += glyph_count;
12952  glyph_n += glyph_count;
12953  } while ((it = it->n) != config_iter);
12954  }
12955 }
12956 NK_INTERN void
12957 nk_font_bake_custom_data(void *img_memory, int img_width, int img_height,
12958  struct nk_recti img_dst, const char *texture_data_mask, int tex_width,
12959  int tex_height, char white, char black)
12960 {
12961  nk_byte *pixels;
12962  int y = 0;
12963  int x = 0;
12964  int n = 0;
12965 
12966  NK_ASSERT(img_memory);
12967  NK_ASSERT(img_width);
12968  NK_ASSERT(img_height);
12969  NK_ASSERT(texture_data_mask);
12970  NK_UNUSED(tex_height);
12971  if (!img_memory || !img_width || !img_height || !texture_data_mask)
12972  return;
12973 
12974  pixels = (nk_byte*)img_memory;
12975  for (y = 0, n = 0; y < tex_height; ++y) {
12976  for (x = 0; x < tex_width; ++x, ++n) {
12977  const int off0 = ((img_dst.x + x) + (img_dst.y + y) * img_width);
12978  const int off1 = off0 + 1 + tex_width;
12979  pixels[off0] = (texture_data_mask[n] == white) ? 0xFF : 0x00;
12980  pixels[off1] = (texture_data_mask[n] == black) ? 0xFF : 0x00;
12981  }
12982  }
12983 }
12984 NK_INTERN void
12985 nk_font_bake_convert(void *out_memory, int img_width, int img_height,
12986  const void *in_memory)
12987 {
12988  int n = 0;
12989  nk_rune *dst;
12990  const nk_byte *src;
12991 
12992  NK_ASSERT(out_memory);
12993  NK_ASSERT(in_memory);
12994  NK_ASSERT(img_width);
12995  NK_ASSERT(img_height);
12996  if (!out_memory || !in_memory || !img_height || !img_width) return;
12997 
12998  dst = (nk_rune*)out_memory;
12999  src = (const nk_byte*)in_memory;
13000  for (n = (int)(img_width * img_height); n > 0; n--)
13001  *dst++ = ((nk_rune)(*src++) << 24) | 0x00FFFFFF;
13002 }
13003 
13004 /* -------------------------------------------------------------
13005  *
13006  * FONT
13007  *
13008  * --------------------------------------------------------------*/
13009 NK_INTERN float
13010 nk_font_text_width(nk_handle handle, float height, const char *text, int len)
13011 {
13012  nk_rune unicode;
13013  int text_len = 0;
13014  float text_width = 0;
13015  int glyph_len = 0;
13016  float scale = 0;
13017 
13018  struct nk_font *font = (struct nk_font*)handle.ptr;
13019  NK_ASSERT(font);
13020  NK_ASSERT(font->glyphs);
13021  if (!font || !text || !len)
13022  return 0;
13023 
13024  scale = height/font->info.height;
13025  glyph_len = text_len = nk_utf_decode(text, &unicode, (int)len);
13026  if (!glyph_len) return 0;
13027  while (text_len <= (int)len && glyph_len) {
13028  const struct nk_font_glyph *g;
13029  if (unicode == NK_UTF_INVALID) break;
13030 
13031  /* query currently drawn glyph information */
13032  g = nk_font_find_glyph(font, unicode);
13033  text_width += g->xadvance * scale;
13034 
13035  /* offset next glyph */
13036  glyph_len = nk_utf_decode(text + text_len, &unicode, (int)len - text_len);
13037  text_len += glyph_len;
13038  }
13039  return text_width;
13040 }
13041 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
13042 NK_INTERN void
13043 nk_font_query_font_glyph(nk_handle handle, float height,
13044  struct nk_user_font_glyph *glyph, nk_rune codepoint, nk_rune next_codepoint)
13045 {
13046  float scale;
13047  const struct nk_font_glyph *g;
13048  struct nk_font *font;
13049 
13050  NK_ASSERT(glyph);
13051  NK_UNUSED(next_codepoint);
13052 
13053  font = (struct nk_font*)handle.ptr;
13054  NK_ASSERT(font);
13055  NK_ASSERT(font->glyphs);
13056  if (!font || !glyph)
13057  return;
13058 
13059  scale = height/font->info.height;
13060  g = nk_font_find_glyph(font, codepoint);
13061  glyph->width = (g->x1 - g->x0) * scale;
13062  glyph->height = (g->y1 - g->y0) * scale;
13063  glyph->offset = nk_vec2(g->x0 * scale, g->y0 * scale);
13064  glyph->xadvance = (g->xadvance * scale);
13065  glyph->uv[0] = nk_vec2(g->u0, g->v0);
13066  glyph->uv[1] = nk_vec2(g->u1, g->v1);
13067 }
13068 #endif
13069 NK_API const struct nk_font_glyph*
13070 nk_font_find_glyph(struct nk_font *font, nk_rune unicode)
13071 {
13072  int i = 0;
13073  int count;
13074  int total_glyphs = 0;
13075  const struct nk_font_glyph *glyph = 0;
13076  const struct nk_font_config *iter = 0;
13077 
13078  NK_ASSERT(font);
13079  NK_ASSERT(font->glyphs);
13080  NK_ASSERT(font->info.ranges);
13081  if (!font || !font->glyphs) return 0;
13082 
13083  glyph = font->fallback;
13084  iter = font->config;
13085  do {count = nk_range_count(iter->range);
13086  for (i = 0; i < count; ++i) {
13087  nk_rune f = iter->range[(i*2)+0];
13088  nk_rune t = iter->range[(i*2)+1];
13089  int diff = (int)((t - f) + 1);
13090  if (unicode >= f && unicode <= t)
13091  return &font->glyphs[((nk_rune)total_glyphs + (unicode - f))];
13092  total_glyphs += diff;
13093  }
13094  } while ((iter = iter->n) != font->config);
13095  return glyph;
13096 }
13097 NK_INTERN void
13098 nk_font_init(struct nk_font *font, float pixel_height,
13099  nk_rune fallback_codepoint, struct nk_font_glyph *glyphs,
13100  const struct nk_baked_font *baked_font, nk_handle atlas)
13101 {
13102  struct nk_baked_font baked;
13103  NK_ASSERT(font);
13104  NK_ASSERT(glyphs);
13105  NK_ASSERT(baked_font);
13106  if (!font || !glyphs || !baked_font)
13107  return;
13108 
13109  baked = *baked_font;
13110  font->fallback = 0;
13111  font->info = baked;
13112  font->scale = (float)pixel_height / (float)font->info.height;
13113  font->glyphs = &glyphs[baked_font->glyph_offset];
13114  font->texture = atlas;
13115  font->fallback_codepoint = fallback_codepoint;
13116  font->fallback = nk_font_find_glyph(font, fallback_codepoint);
13117 
13118  font->handle.height = font->info.height * font->scale;
13119  font->handle.width = nk_font_text_width;
13120  font->handle.userdata.ptr = font;
13121 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
13122  font->handle.query = nk_font_query_font_glyph;
13123  font->handle.texture = font->texture;
13124 #endif
13125 }
13126 
13127 /* ---------------------------------------------------------------------------
13128  *
13129  * DEFAULT FONT
13130  *
13131  * ProggyClean.ttf
13132  * Copyright (c) 2004, 2005 Tristan Grimmer
13133  * MIT license (see License.txt in http://www.upperbounds.net/download/ProggyClean.ttf.zip)
13134  * Download and more information at http://upperbounds.net
13135  *-----------------------------------------------------------------------------*/
13136 #ifdef __clang__
13137 #pragma clang diagnostic push
13138 #pragma clang diagnostic ignored "-Woverlength-strings"
13139 #elif defined(__GNUC__) || defined(__GNUG__)
13140 #pragma GCC diagnostic push
13141 #pragma GCC diagnostic ignored "-Woverlength-strings"
13142 #endif
13143 
13144 #ifdef NK_INCLUDE_DEFAULT_FONT
13145 
13146 NK_GLOBAL const char nk_proggy_clean_ttf_compressed_data_base85[11980+1] =
13147  "7])#######hV0qs'/###[),##/l:$#Q6>##5[n42>c-TH`->>#/e>11NNV=Bv(*:.F?uu#(gRU.o0XGH`$vhLG1hxt9?W`#,5LsCp#-i>.r$<$6pD>Lb';9Crc6tgXmKVeU2cD4Eo3R/"
13148  "2*>]b(MC;$jPfY.;h^`IWM9<Lh2TlS+f-s$o6Q<BWH`YiU.xfLq$N;$0iR/GX:U(jcW2p/W*q?-qmnUCI;jHSAiFWM.R*kU@C=GH?a9wp8f$e.-4^Qg1)Q-GL(lf(r/7GrRgwV%MS=C#"
13149  "`8ND>Qo#t'X#(v#Y9w0#1D$CIf;W'#pWUPXOuxXuU(H9M(1<q-UE31#^-V'8IRUo7Qf./L>=Ke$$'5F%)]0^#0X@U.a<r:QLtFsLcL6##lOj)#.Y5<-R&KgLwqJfLgN&;Q?gI^#DY2uL"
13150  "i@^rMl9t=cWq6##weg>$FBjVQTSDgEKnIS7EM9>ZY9w0#L;>>#Mx&4Mvt//L[MkA#W@lK.N'[0#7RL_&#w+F%HtG9M#XL`N&.,GM4Pg;-<nLENhvx>-VsM.M0rJfLH2eTM`*oJMHRC`N"
13151  "kfimM2J,W-jXS:)r0wK#@Fge$U>`w'N7G#$#fB#$E^$#:9:hk+eOe--6x)F7*E%?76%^GMHePW-Z5l'&GiF#$956:rS?dA#fiK:)Yr+`&#0j@'DbG&#^$PG.Ll+DNa<XCMKEV*N)LN/N"
13152  "*b=%Q6pia-Xg8I$<MR&,VdJe$<(7G;Ckl'&hF;;$<_=X(b.RS%%)###MPBuuE1V:v&cX&#2m#(&cV]`k9OhLMbn%s$G2,B$BfD3X*sp5#l,$R#]x_X1xKX%b5U*[r5iMfUo9U`N99hG)"
13153  "tm+/Us9pG)XPu`<0s-)WTt(gCRxIg(%6sfh=ktMKn3j)<6<b5Sk_/0(^]AaN#(p/L>&VZ>1i%h1S9u5o@YaaW$e+b<TWFn/Z:Oh(Cx2$lNEoN^e)#CFY@@I;BOQ*sRwZtZxRcU7uW6CX"
13154  "ow0i(?$Q[cjOd[P4d)]>ROPOpxTO7Stwi1::iB1q)C_=dV26J;2,]7op$]uQr@_V7$q^%lQwtuHY]=DX,n3L#0PHDO4f9>dC@O>HBuKPpP*E,N+b3L#lpR/MrTEH.IAQk.a>D[.e;mc."
13155  "x]Ip.PH^'/aqUO/$1WxLoW0[iLA<QT;5HKD+@qQ'NQ(3_PLhE48R.qAPSwQ0/WK?Z,[x?-J;jQTWA0X@KJ(_Y8N-:/M74:/-ZpKrUss?d#dZq]DAbkU*JqkL+nwX@@47`5>w=4h(9.`G"
13156  "CRUxHPeR`5Mjol(dUWxZa(>STrPkrJiWx`5U7F#.g*jrohGg`cg:lSTvEY/EV_7H4Q9[Z%cnv;JQYZ5q.l7Zeas:HOIZOB?G<Nald$qs]@]L<J7bR*>gv:[7MI2k).'2($5FNP&EQ(,)"
13157  "U]W]+fh18.vsai00);D3@4ku5P?DP8aJt+;qUM]=+b'8@;mViBKx0DE[-auGl8:PJ&Dj+M6OC]O^((##]`0i)drT;-7X`=-H3[igUnPG-NZlo.#k@h#=Ork$m>a>$-?Tm$UV(?#P6YY#"
13158  "'/###xe7q.73rI3*pP/$1>s9)W,JrM7SN]'/4C#v$U`0#V.[0>xQsH$fEmPMgY2u7Kh(G%siIfLSoS+MK2eTM$=5,M8p`A.;_R%#u[K#$x4AG8.kK/HSB==-'Ie/QTtG?-.*^N-4B/ZM"
13159  "_3YlQC7(p7q)&](`6_c)$/*JL(L-^(]$wIM`dPtOdGA,U3:w2M-0<q-]L_?^)1vw'.,MRsqVr.L;aN&#/EgJ)PBc[-f>+WomX2u7lqM2iEumMTcsF?-aT=Z-97UEnXglEn1K-bnEO`gu"
13160  "Ft(c%=;Am_Qs@jLooI&NX;]0#j4#F14;gl8-GQpgwhrq8'=l_f-b49'UOqkLu7-##oDY2L(te+Mch&gLYtJ,MEtJfLh'x'M=$CS-ZZ%P]8bZ>#S?YY#%Q&q'3^Fw&?D)UDNrocM3A76/"
13161  "/oL?#h7gl85[qW/NDOk%16ij;+:1a'iNIdb-ou8.P*w,v5#EI$TWS>Pot-R*H'-SEpA:g)f+O$%%`kA#G=8RMmG1&O`>to8bC]T&$,n.LoO>29sp3dt-52U%VM#q7'DHpg+#Z9%H[K<L"
13162  "%a2E-grWVM3@2=-k22tL]4$##6We'8UJCKE[d_=%wI;'6X-GsLX4j^SgJ$##R*w,vP3wK#iiW&#*h^D&R?jp7+/u&#(AP##XU8c$fSYW-J95_-Dp[g9wcO&#M-h1OcJlc-*vpw0xUX&#"
13163  "OQFKNX@QI'IoPp7nb,QU//MQ&ZDkKP)X<WSVL(68uVl&#c'[0#(s1X&xm$Y%B7*K:eDA323j998GXbA#pwMs-jgD$9QISB-A_(aN4xoFM^@C58D0+Q+q3n0#3U1InDjF682-SjMXJK)("
13164  "h$hxua_K]ul92%'BOU&#BRRh-slg8KDlr:%L71Ka:.A;%YULjDPmL<LYs8i#XwJOYaKPKc1h:'9Ke,g)b),78=I39B;xiY$bgGw-&.Zi9InXDuYa%G*f2Bq7mn9^#p1vv%#(Wi-;/Z5h"
13165  "o;#2:;%d&#x9v68C5g?ntX0X)pT`;%pB3q7mgGN)3%(P8nTd5L7GeA-GL@+%J3u2:(Yf>et`e;)f#Km8&+DC$I46>#Kr]]u-[=99tts1.qb#q72g1WJO81q+eN'03'eM>&1XxY-caEnO"
13166  "j%2n8)),?ILR5^.Ibn<-X-Mq7[a82Lq:F&#ce+S9wsCK*x`569E8ew'He]h:sI[2LM$[guka3ZRd6:t%IG:;$%YiJ:Nq=?eAw;/:nnDq0(CYcMpG)qLN4$##&J<j$UpK<Q4a1]MupW^-"
13167  "sj_$%[HK%'F####QRZJ::Y3EGl4'@%FkiAOg#p[##O`gukTfBHagL<LHw%q&OV0##F=6/:chIm0@eCP8X]:kFI%hl8hgO@RcBhS-@Qb$%+m=hPDLg*%K8ln(wcf3/'DW-$.lR?n[nCH-"
13168  "eXOONTJlh:.RYF%3'p6sq:UIMA945&^HFS87@$EP2iG<-lCO$%c`uKGD3rC$x0BL8aFn--`ke%#HMP'vh1/R&O_J9'um,.<tx[@%wsJk&bUT2`0uMv7gg#qp/ij.L56'hl;.s5CUrxjO"
13169  "M7-##.l+Au'A&O:-T72L]P`&=;ctp'XScX*rU.>-XTt,%OVU4)S1+R-#dg0/Nn?Ku1^0f$B*P:Rowwm-`0PKjYDDM'3]d39VZHEl4,.j']Pk-M.h^&:0FACm$maq-&sgw0t7/6(^xtk%"
13170  "LuH88Fj-ekm>GA#_>568x6(OFRl-IZp`&b,_P'$M<Jnq79VsJW/mWS*PUiq76;]/NM_>hLbxfc$mj`,O;&%W2m`Zh:/)Uetw:aJ%]K9h:TcF]u_-Sj9,VK3M.*'&0D[Ca]J9gp8,kAW]"
13171  "%(?A%R$f<->Zts'^kn=-^@c4%-pY6qI%J%1IGxfLU9CP8cbPlXv);C=b),<2mOvP8up,UVf3839acAWAW-W?#ao/^#%KYo8fRULNd2.>%m]UK:n%r$'sw]J;5pAoO_#2mO3n,'=H5(et"
13172  "Hg*`+RLgv>=4U8guD$I%D:W>-r5V*%j*W:Kvej.Lp$<M-SGZ':+Q_k+uvOSLiEo(<aD/K<CCc`'Lx>'?;++O'>()jLR-^u68PHm8ZFWe+ej8h:9r6L*0//c&iH&R8pRbA#Kjm%upV1g:"
13173  "a_#Ur7FuA#(tRh#.Y5K+@?3<-8m0$PEn;J:rh6?I6uG<-`wMU'ircp0LaE_OtlMb&1#6T.#FDKu#1Lw%u%+GM+X'e?YLfjM[VO0MbuFp7;>Q&#WIo)0@F%q7c#4XAXN-U&VB<HFF*qL("
13174  "$/V,;(kXZejWO`<[5?\?ewY(*9=%wDc;,u<'9t3W-(H1th3+G]ucQ]kLs7df($/*JL]@*t7Bu_G3_7mp7<iaQjO@.kLg;x3B0lqp7Hf,^Ze7-##@/c58Mo(3;knp0%)A7?-W+eI'o8)b<"
13175  "nKnw'Ho8C=Y>pqB>0ie&jhZ[?iLR@@_AvA-iQC(=ksRZRVp7`.=+NpBC%rh&3]R:8XDmE5^V8O(x<<aG/1N$#FX$0V5Y6x'aErI3I$7x%E`v<-BY,)%-?Psf*l?%C3.mM(=/M0:JxG'?"
13176  "7WhH%o'a<-80g0NBxoO(GH<dM]n.+%q@jH?f.UsJ2Ggs&4<-e47&Kl+f//9@`b+?.TeN_&B8Ss?v;^Trk;f#YvJkl&w$]>-+k?'(<S:68tq*WoDfZu';mM?8X[ma8W%*`-=;D.(nc7/;"
13177  ")g:T1=^J$&BRV(-lTmNB6xqB[@0*o.erM*<SWF]u2=st-*(6v>^](H.aREZSi,#1:[IXaZFOm<-ui#qUq2$##Ri;u75OK#(RtaW-K-F`S+cF]uN`-KMQ%rP/Xri.LRcB##=YL3BgM/3M"
13178  "D?@f&1'BW-)Ju<L25gl8uhVm1hL$##*8###'A3/LkKW+(^rWX?5W_8g)a(m&K8P>#bmmWCMkk&#TR`C,5d>g)F;t,4:@_l8G/5h4vUd%&%950:VXD'QdWoY-F$BtUwmfe$YqL'8(PWX("
13179  "P?^@Po3$##`MSs?DWBZ/S>+4%>fX,VWv/w'KD`LP5IbH;rTV>n3cEK8U#bX]l-/V+^lj3;vlMb&[5YQ8#pekX9JP3XUC72L,,?+Ni&co7ApnO*5NK,((W-i:$,kp'UDAO(G0Sq7MVjJs"
13180  "bIu)'Z,*[>br5fX^:FPAWr-m2KgL<LUN098kTF&#lvo58=/vjDo;.;)Ka*hLR#/k=rKbxuV`>Q_nN6'8uTG&#1T5g)uLv:873UpTLgH+#FgpH'_o1780Ph8KmxQJ8#H72L4@768@Tm&Q"
13181  "h4CB/5OvmA&,Q&QbUoi$a_%3M01H)4x7I^&KQVgtFnV+;[Pc>[m4k//,]1?#`VY[Jr*3&&slRfLiVZJ:]?=K3Sw=[$=uRB?3xk48@aeg<Z'<$#4H)6,>e0jT6'N#(q%.O=?2S]u*(m<-"
13182  "V8J'(1)G][68hW$5'q[GC&5j`TE?m'esFGNRM)j,ffZ?-qx8;->g4t*:CIP/[Qap7/9'#(1sao7w-.qNUdkJ)tCF&#B^;xGvn2r9FEPFFFcL@.iFNkTve$m%#QvQS8U@)2Z+3K:AKM5i"
13183  "sZ88+dKQ)W6>J%CL<KE>`.d*(B`-n8D9oK<Up]c$X$(,)M8Zt7/[rdkqTgl-0cuGMv'?>-XV1q['-5k'cAZ69e;D_?$ZPP&s^+7])$*$#@QYi9,5P&#9r+$%CE=68>K8r0=dSC%%(@p7"
13184  ".m7jilQ02'0-VWAg<a/''3u.=4L$Y)6k/K:_[3=&jvL<L0C/2'v:^;-DIBW,B4E68:kZ;%?8(Q8BH=kO65BW?xSG&#@uU,DS*,?.+(o(#1vCS8#CHF>TlGW'b)Tq7VT9q^*^$$.:&N@@"
13185  "$&)WHtPm*5_rO0&e%K&#-30j(E4#'Zb.o/(Tpm$>K'f@[PvFl,hfINTNU6u'0pao7%XUp9]5.>%h`8_=VYbxuel.NTSsJfLacFu3B'lQSu/m6-Oqem8T+oE--$0a/k]uj9EwsG>%veR*"
13186  "hv^BFpQj:K'#SJ,sB-'#](j.Lg92rTw-*n%@/;39rrJF,l#qV%OrtBeC6/,;qB3ebNW[?,Hqj2L.1NP&GjUR=1D8QaS3Up&@*9wP?+lo7b?@%'k4`p0Z$22%K3+iCZj?XJN4Nm&+YF]u"
13187  "@-W$U%VEQ/,,>>#)D<h#`)h0:<Q6909ua+&VU%n2:cG3FJ-%@Bj-DgLr`Hw&HAKjKjseK</xKT*)B,N9X3]krc12t'pgTV(Lv-tL[xg_%=M_q7a^x?7Ubd>#%8cY#YZ?=,`Wdxu/ae&#"
13188  "w6)R89tI#6@s'(6Bf7a&?S=^ZI_kS&ai`&=tE72L_D,;^R)7[$s<Eh#c&)q.MXI%#v9ROa5FZO%sF7q7Nwb&#ptUJ:aqJe$Sl68%.D###EC><?-aF&#RNQv>o8lKN%5/$(vdfq7+ebA#"
13189  "u1p]ovUKW&Y%q]'>$1@-[xfn$7ZTp7mM,G,Ko7a&Gu%G[RMxJs[0MM%wci.LFDK)(<c`Q8N)jEIF*+?P2a8g%)$q]o2aH8C&<SibC/q,(e:v;-b#6[$NtDZ84Je2KNvB#$P5?tQ3nt(0"
13190  "d=j.LQf./Ll33+(;q3L-w=8dX$#WF&uIJ@-bfI>%:_i2B5CsR8&9Z&#=mPEnm0f`<&c)QL5uJ#%u%lJj+D-r;BoF&#4DoS97h5g)E#o:&S4weDF,9^Hoe`h*L+_a*NrLW-1pG_&2UdB8"
13191  "6e%B/:=>)N4xeW.*wft-;$'58-ESqr<b?UI(_%@[P46>#U`'6AQ]m&6/`Z>#S?YY#Vc;r7U2&326d=w&H####?TZ`*4?&.MK?LP8Vxg>$[QXc%QJv92.(Db*B)gb*BM9dM*hJMAo*c&#"
13192  "b0v=Pjer]$gG&JXDf->'StvU7505l9$AFvgYRI^&<^b68?j#q9QX4SM'RO#&sL1IM.rJfLUAj221]d##DW=m83u5;'bYx,*Sl0hL(W;;$doB&O/TQ:(Z^xBdLjL<Lni;''X.`$#8+1GD"
13193  ":k$YUWsbn8ogh6rxZ2Z9]%nd+>V#*8U_72Lh+2Q8Cj0i:6hp&$C/:p(HK>T8Y[gHQ4`4)'$Ab(Nof%V'8hL&#<NEdtg(n'=S1A(Q1/I&4([%dM`,Iu'1:_hL>SfD07&6D<fp8dHM7/g+"
13194  "tlPN9J*rKaPct&?'uBCem^jn%9_K)<,C5K3s=5g&GmJb*[SYq7K;TRLGCsM-$$;S%:Y@r7AK0pprpL<Lrh,q7e/%KWK:50I^+m'vi`3?%Zp+<-d+$L-Sv:@.o19n$s0&39;kn;S%BSq*"
13195  "$3WoJSCLweV[aZ'MQIjO<7;X-X;&+dMLvu#^UsGEC9WEc[X(wI7#2.(F0jV*eZf<-Qv3J-c+J5AlrB#$p(H68LvEA'q3n0#m,[`*8Ft)FcYgEud]CWfm68,(aLA$@EFTgLXoBq/UPlp7"
13196  ":d[/;r_ix=:TF`S5H-b<LI&HY(K=h#)]Lk$K14lVfm:x$H<3^Ql<M`$OhapBnkup'D#L$Pb_`N*g]2e;X/Dtg,bsj&K#2[-:iYr'_wgH)NUIR8a1n#S?Yej'h8^58UbZd+^FKD*T@;6A"
13197  "7aQC[K8d-(v6GI$x:T<&'Gp5Uf>@M.*J:;$-rv29'M]8qMv-tLp,'886iaC=Hb*YJoKJ,(j%K=H`K.v9HggqBIiZu'QvBT.#=)0ukruV&.)3=(^1`o*Pj4<-<aN((^7('#Z0wK#5GX@7"
13198  "u][`*S^43933A4rl][`*O4CgLEl]v$1Q3AeF37dbXk,.)vj#x'd`;qgbQR%FW,2(?LO=s%Sc68%NP'##Aotl8x=BE#j1UD([3$M(]UI2LX3RpKN@;/#f'f/&_mt&F)XdF<9t4)Qa.*kT"
13199  "LwQ'(TTB9.xH'>#MJ+gLq9-##@HuZPN0]u:h7.T..G:;$/Usj(T7`Q8tT72LnYl<-qx8;-HV7Q-&Xdx%1a,hC=0u+HlsV>nuIQL-5<N?)NBS)QN*_I,?&)2'IM%L3I)X((e/dl2&8'<M"
13200  ":^#M*Q+[T.Xri.LYS3v%fF`68h;b-X[/En'CR.q7E)p'/kle2HM,u;^%OKC-N+Ll%F9CF<Nf'^#t2L,;27W:0O@6##U6W7:$rJfLWHj$#)woqBefIZ.PK<b*t7ed;p*_m;4ExK#h@&]>"
13201  "_>@kXQtMacfD.m-VAb8;IReM3$wf0''hra*so568'Ip&vRs849'MRYSp%:t:h5qSgwpEr$B>Q,;s(C#$)`svQuF$##-D,##,g68@2[T;.XSdN9Qe)rpt._K-#5wF)sP'##p#C0c%-Gb%"
13202  "hd+<-j'Ai*x&&HMkT]C'OSl##5RG[JXaHN;d'uA#x._U;.`PU@(Z3dt4r152@:v,'R.Sj'w#0<-;kPI)FfJ&#AYJ&#//)>-k=m=*XnK$>=)72L]0I%>.G690a:$##<,);?;72#?x9+d;"
13203  "^V'9;jY@;)br#q^YQpx:X#Te$Z^'=-=bGhLf:D6&bNwZ9-ZD#n^9HhLMr5G;']d&6'wYmTFmL<LD)F^%[tC'8;+9E#C$g%#5Y>q9wI>P(9mI[>kC-ekLC/R&CH+s'B;K-M6$EB%is00:"
13204  "+A4[7xks.LrNk0&E)wILYF@2L'0Nb$+pv<(2.768/FrY&h$^3i&@+G%JT'<-,v`3;_)I9M^AE]CN?Cl2AZg+%4iTpT3<n-&%H%b<FDj2M<hH=&Eh<2Len$b*aTX=-8QxN)k11IM1c^j%"
13205  "9s<L<NFSo)B?+<-(GxsF,^-Eh@$4dXhN$+#rxK8'je'D7k`e;)2pYwPA'_p9&@^18ml1^[@g4t*[JOa*[=Qp7(qJ_oOL^('7fB&Hq-:sf,sNj8xq^>$U4O]GKx'm9)b@p7YsvK3w^YR-"
13206  "CdQ*:Ir<($u&)#(&?L9Rg3H)4fiEp^iI9O8KnTj,]H?D*r7'M;PwZ9K0E^k&-cpI;.p/6_vwoFMV<->#%Xi.LxVnrU(4&8/P+:hLSKj$#U%]49t'I:rgMi'FL@a:0Y-uA[39',(vbma*"
13207  "hU%<-SRF`Tt:542R_VV$p@[p8DV[A,?1839FWdF<TddF<9Ah-6&9tWoDlh]&1SpGMq>Ti1O*H&#(AL8[_P%.M>v^-))qOT*F5Cq0`Ye%+$B6i:7@0IX<N+T+0MlMBPQ*Vj>SsD<U4JHY"
13208  "8kD2)2fU/M#$e.)T4,_=8hLim[&);?UkK'-x?'(:siIfL<$pFM`i<?%W(mGDHM%>iWP,##P`%/L<eXi:@Z9C.7o=@(pXdAO/NLQ8lPl+HPOQa8wD8=^GlPa8TKI1CjhsCTSLJM'/Wl>-"
13209  "S(qw%sf/@%#B6;/U7K]uZbi^Oc^2n<bhPmUkMw>%t<)'mEVE''n`WnJra$^TKvX5B>;_aSEK',(hwa0:i4G?.Bci.(X[?b*($,=-n<.Q%`(X=?+@Am*Js0&=3bh8K]mL<LoNs'6,'85`"
13210  "0?t/'_U59@]ddF<#LdF<eWdF<OuN/45rY<-L@&#+fm>69=Lb,OcZV/);TTm8VI;?%OtJ<(b4mq7M6:u?KRdF<gR@2L=FNU-<b[(9c/ML3m;Z[$oF3g)GAWqpARc=<ROu7cL5l;-[A]%/"
13211  "+fsd;l#SafT/f*W]0=O'$(Tb<[)*@e775R-:Yob%g*>l*:xP?Yb.5)%w_I?7uk5JC+FS(m#i'k.'a0i)9<7b'fs'59hq$*5Uhv##pi^8+hIEBF`nvo`;'l0.^S1<-wUK2/Coh58KKhLj"
13212  "M=SO*rfO`+qC`W-On.=AJ56>>i2@2LH6A:&5q`?9I3@@'04&p2/LVa*T-4<-i3;M9UvZd+N7>b*eIwg:CC)c<>nO&#<IGe;__.thjZl<%w(Wk2xmp4Q@I#I9,DF]u7-P=.-_:YJ]aS@V"
13213  "?6*C()dOp7:WL,b&3Rg/.cmM9&r^>$(>.Z-I&J(Q0Hd5Q%7Co-b`-c<N(6r@ip+AurK<m86QIth*#v;-OBqi+L7wDE-Ir8K['m+DDSLwK&/.?-V%U_%3:qKNu$_b*B-kp7NaD'QdWQPK"
13214  "Yq[@>P)hI;*_F]u`Rb[.j8_Q/<&>uu+VsH$sM9TA%?)(vmJ80),P7E>)tjD%2L=-t#fK[%`v=Q8<FfNkgg^oIbah*#8/Qt$F&:K*-(N/'+1vMB,u()-a.VUU*#[e%gAAO(S>WlA2);Sa"
13215  ">gXm8YB`1d@K#n]76-a$U,mF<fX]idqd)<3,]J7JmW4`6]uks=4-72L(jEk+:bJ0M^q-8Dm_Z?0olP1C9Sa&H[d&c$ooQUj]Exd*3ZM@-WGW2%s',B-_M%>%Ul:#/'xoFM9QX-$.QN'>"
13216  "[%$Z$uF6pA6Ki2O5:8w*vP1<-1`[G,)-m#>0`P&#eb#.3i)rtB61(o'$?X3B</R90;eZ]%Ncq;-Tl]#F>2Qft^ae_5tKL9MUe9b*sLEQ95C&`=G?@Mj=wh*'3E>=-<)Gt*Iw)'QG:`@I"
13217  "wOf7&]1i'S01B+Ev/Nac#9S;=;YQpg_6U`*kVY39xK,[/6Aj7:'1Bm-_1EYfa1+o&o4hp7KN_Q(OlIo@S%;jVdn0'1<Vc52=u`3^o-n1'g4v58Hj&6_t7$##?M)c<$bgQ_'SY((-xkA#"
13218  "Y(,p'H9rIVY-b,'%bCPF7.J<Up^,(dU1VY*5#WkTU>h19w,WQhLI)3S#f$2(eb,jr*b;3Vw]*7NH%$c4Vs,eD9>XW8?N]o+(*pgC%/72LV-u<Hp,3@e^9UB1J+ak9-TN/mhKPg+AJYd$"
13219  "MlvAF_jCK*.O-^(63adMT->W%iewS8W6m2rtCpo'RS1R84=@paTKt)>=%&1[)*vp'u+x,VrwN;&]kuO9JDbg=pO$J*.jVe;u'm0dr9l,<*wMK*Oe=g8lV_KEBFkO'oU]^=[-792#ok,)"
13220  "i]lR8qQ2oA8wcRCZ^7w/Njh;?.stX?Q1>S1q4Bn$)K1<-rGdO'$Wr.Lc.CG)$/*JL4tNR/,SVO3,aUw'DJN:)Ss;wGn9A32ijw%FL+Z0Fn.U9;reSq)bmI32U==5ALuG&#Vf1398/pVo"
13221  "1*c-(aY168o<`JsSbk-,1N;$>0:OUas(3:8Z972LSfF8eb=c-;>SPw7.6hn3m`9^Xkn(r.qS[0;T%&Qc=+STRxX'q1BNk3&*eu2;&8q$&x>Q#Q7^Tf+6<(d%ZVmj2bDi%.3L2n+4W'$P"
13222  "iDDG)g,r%+?,$@?uou5tSe2aN_AQU*<h`e-GI7)?OK2A.d7_c)?wQ5AS@DL3r#7fSkgl6-++D:'A,uq7SvlB$pcpH'q3n0#_%dY#xCpr-l<F0NR@-##FEV6NTF6##$l84N1w?AO>'IAO"
13223  "URQ##V^Fv-XFbGM7Fl(N<3DhLGF%q.1rC$#:T__&Pi68%0xi_&[qFJ(77j_&JWoF.V735&T,[R*:xFR*K5>>#`bW-?4Ne_&6Ne_&6Ne_&n`kr-#GJcM6X;uM6X;uM(.a..^2TkL%oR(#"
13224  ";u.T%fAr%4tJ8&><1=GHZ_+m9/#H1F^R#SC#*N=BA9(D?v[UiFY>>^8p,KKF.W]L29uLkLlu/+4T<XoIB&hx=T1PcDaB&;HH+-AFr?(m9HZV)FKS8JCw;SD=6[^/DZUL`EUDf]GGlG&>"
13225  "w$)F./^n3+rlo+DB;5sIYGNk+i1t-69Jg--0pao7Sm#K)pdHW&;LuDNH@H>#/X-TI(;P>#,Gc>#0Su>#4`1?#8lC?#<xU?#@.i?#D:%@#HF7@#LRI@#P_[@#Tkn@#Xw*A#]-=A#a9OA#"
13226  "d<F&#*;G##.GY##2Sl##6`($#:l:$#>xL$#B.`$#F:r$#JF.%#NR@%#R_R%#Vke%#Zww%#_-4&#3^Rh%Sflr-k'MS.o?.5/sWel/wpEM0%3'/1)K^f1-d>G21&v(35>V`39V7A4=onx4"
13227  "A1OY5EI0;6Ibgr6M$HS7Q<)58C5w,;WoA*#[%T*#`1g*#d=#+#hI5+#lUG+#pbY+#tnl+#x$),#&1;,#*=M,#.I`,#2Ur,#6b.-#;w[H#iQtA#m^0B#qjBB#uvTB##-hB#'9$C#+E6C#"
13228  "/QHC#3^ZC#7jmC#;v)D#?,<D#C8ND#GDaD#KPsD#O]/E#g1A5#KA*1#gC17#MGd;#8(02#L-d3#rWM4#Hga1#,<w0#T.j<#O#'2#CYN1#qa^:#_4m3#o@/=#eG8=#t8J5#`+78#4uI-#"
13229  "m3B2#SB[8#Q0@8#i[*9#iOn8#1Nm;#^sN9#qh<9#:=x-#P;K2#$%X9#bC+.#Rg;<#mN=.#MTF.#RZO.#2?)4#Y#(/#[)1/#b;L/#dAU/#0Sv;#lY$0#n`-0#sf60#(F24#wrH0#%/e0#"
13230  "TmD<#%JSMFove:CTBEXI:<eh2g)B,3h2^G3i;#d3jD>)4kMYD4lVu`4m`:&5niUA5@(A5BA1]PBB:xlBCC=2CDLXMCEUtiCf&0g2'tN?PGT4CPGT4CPGT4CPGT4CPGT4CPGT4CPGT4CP"
13231  "GT4CPGT4CPGT4CPGT4CPGT4CPGT4CP-qekC`.9kEg^+F$kwViFJTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5o,^<-28ZI'O?;xp"
13232  "O?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xp;7q-#lLYI:xvD=#";
13233 
13234 #endif /* NK_INCLUDE_DEFAULT_FONT */
13235 
13236 #define NK_CURSOR_DATA_W 90
13237 #define NK_CURSOR_DATA_H 27
13238 NK_GLOBAL const char nk_custom_cursor_data[NK_CURSOR_DATA_W * NK_CURSOR_DATA_H + 1] =
13239 {
13240  "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX"
13241  "..- -X.....X- X.X - X.X -X.....X - X.....X"
13242  "--- -XXX.XXX- X...X - X...X -X....X - X....X"
13243  "X - X.X - X.....X - X.....X -X...X - X...X"
13244  "XX - X.X -X.......X- X.......X -X..X.X - X.X..X"
13245  "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X"
13246  "X..X - X.X - X.X - X.X -XX X.X - X.X XX"
13247  "X...X - X.X - X.X - XX X.X XX - X.X - X.X "
13248  "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X "
13249  "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X "
13250  "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X "
13251  "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X "
13252  "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X "
13253  "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X "
13254  "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X "
13255  "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X "
13256  "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX "
13257  "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------"
13258  "X.X X..X - -X.......X- X.......X - XX XX - "
13259  "XX X..X - - X.....X - X.....X - X.X X.X - "
13260  " X..X - X...X - X...X - X..X X..X - "
13261  " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - "
13262  "------------ - X - X -X.....................X- "
13263  " ----------------------------------- X...XXXXXXXXXXXXX...X - "
13264  " - X..X X..X - "
13265  " - X.X X.X - "
13266  " - XX XX - "
13267 };
13268 
13269 #ifdef __clang__
13270 #pragma clang diagnostic pop
13271 #elif defined(__GNUC__) || defined(__GNUG__)
13272 #pragma GCC diagnostic pop
13273 #endif
13274 
13275 NK_GLOBAL unsigned char *nk__barrier;
13276 NK_GLOBAL unsigned char *nk__barrier2;
13277 NK_GLOBAL unsigned char *nk__barrier3;
13278 NK_GLOBAL unsigned char *nk__barrier4;
13279 NK_GLOBAL unsigned char *nk__dout;
13280 
13281 NK_INTERN unsigned int
13282 nk_decompress_length(unsigned char *input)
13283 {
13284  return (unsigned int)((input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11]);
13285 }
13286 NK_INTERN void
13287 nk__match(unsigned char *data, unsigned int length)
13288 {
13289  /* INVERSE of memmove... write each byte before copying the next...*/
13290  NK_ASSERT (nk__dout + length <= nk__barrier);
13291  if (nk__dout + length > nk__barrier) { nk__dout += length; return; }
13292  if (data < nk__barrier4) { nk__dout = nk__barrier+1; return; }
13293  while (length--) *nk__dout++ = *data++;
13294 }
13295 NK_INTERN void
13296 nk__lit(unsigned char *data, unsigned int length)
13297 {
13298  NK_ASSERT (nk__dout + length <= nk__barrier);
13299  if (nk__dout + length > nk__barrier) { nk__dout += length; return; }
13300  if (data < nk__barrier2) { nk__dout = nk__barrier+1; return; }
13301  NK_MEMCPY(nk__dout, data, length);
13302  nk__dout += length;
13303 }
13304 NK_INTERN unsigned char*
13305 nk_decompress_token(unsigned char *i)
13306 {
13307  #define nk__in2(x) ((i[x] << 8) + i[(x)+1])
13308  #define nk__in3(x) ((i[x] << 16) + nk__in2((x)+1))
13309  #define nk__in4(x) ((i[x] << 24) + nk__in3((x)+1))
13310 
13311  if (*i >= 0x20) { /* use fewer if's for cases that expand small */
13312  if (*i >= 0x80) nk__match(nk__dout-i[1]-1, (unsigned int)i[0] - 0x80 + 1), i += 2;
13313  else if (*i >= 0x40) nk__match(nk__dout-(nk__in2(0) - 0x4000 + 1), (unsigned int)i[2]+1), i += 3;
13314  else /* *i >= 0x20 */ nk__lit(i+1, (unsigned int)i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1);
13315  } else { /* more ifs for cases that expand large, since overhead is amortized */
13316  if (*i >= 0x18) nk__match(nk__dout-(unsigned int)(nk__in3(0) - 0x180000 + 1), (unsigned int)i[3]+1), i += 4;
13317  else if (*i >= 0x10) nk__match(nk__dout-(unsigned int)(nk__in3(0) - 0x100000 + 1), (unsigned int)nk__in2(3)+1), i += 5;
13318  else if (*i >= 0x08) nk__lit(i+2, (unsigned int)nk__in2(0) - 0x0800 + 1), i += 2 + (nk__in2(0) - 0x0800 + 1);
13319  else if (*i == 0x07) nk__lit(i+3, (unsigned int)nk__in2(1) + 1), i += 3 + (nk__in2(1) + 1);
13320  else if (*i == 0x06) nk__match(nk__dout-(unsigned int)(nk__in3(1)+1), i[4]+1u), i += 5;
13321  else if (*i == 0x04) nk__match(nk__dout-(unsigned int)(nk__in3(1)+1), (unsigned int)nk__in2(4)+1u), i += 6;
13322  }
13323  return i;
13324 }
13325 NK_INTERN unsigned int
13326 nk_adler32(unsigned int adler32, unsigned char *buffer, unsigned int buflen)
13327 {
13328  const unsigned long ADLER_MOD = 65521;
13329  unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16;
13330  unsigned long blocklen, i;
13331 
13332  blocklen = buflen % 5552;
13333  while (buflen) {
13334  for (i=0; i + 7 < blocklen; i += 8) {
13335  s1 += buffer[0]; s2 += s1;
13336  s1 += buffer[1]; s2 += s1;
13337  s1 += buffer[2]; s2 += s1;
13338  s1 += buffer[3]; s2 += s1;
13339  s1 += buffer[4]; s2 += s1;
13340  s1 += buffer[5]; s2 += s1;
13341  s1 += buffer[6]; s2 += s1;
13342  s1 += buffer[7]; s2 += s1;
13343  buffer += 8;
13344  }
13345  for (; i < blocklen; ++i) {
13346  s1 += *buffer++; s2 += s1;
13347  }
13348 
13349  s1 %= ADLER_MOD; s2 %= ADLER_MOD;
13350  buflen -= (unsigned int)blocklen;
13351  blocklen = 5552;
13352  }
13353  return (unsigned int)(s2 << 16) + (unsigned int)s1;
13354 }
13355 NK_INTERN unsigned int
13356 nk_decompress(unsigned char *output, unsigned char *i, unsigned int length)
13357 {
13358  unsigned int olen;
13359  if (nk__in4(0) != 0x57bC0000) return 0;
13360  if (nk__in4(4) != 0) return 0; /* error! stream is > 4GB */
13361  olen = nk_decompress_length(i);
13362  nk__barrier2 = i;
13363  nk__barrier3 = i+length;
13364  nk__barrier = output + olen;
13365  nk__barrier4 = output;
13366  i += 16;
13367 
13368  nk__dout = output;
13369  for (;;) {
13370  unsigned char *old_i = i;
13371  i = nk_decompress_token(i);
13372  if (i == old_i) {
13373  if (*i == 0x05 && i[1] == 0xfa) {
13374  NK_ASSERT(nk__dout == output + olen);
13375  if (nk__dout != output + olen) return 0;
13376  if (nk_adler32(1, output, olen) != (unsigned int) nk__in4(2))
13377  return 0;
13378  return olen;
13379  } else {
13380  NK_ASSERT(0); /* NOTREACHED */
13381  return 0;
13382  }
13383  }
13384  NK_ASSERT(nk__dout <= output + olen);
13385  if (nk__dout > output + olen)
13386  return 0;
13387  }
13388 }
13389 NK_INTERN unsigned int
13390 nk_decode_85_byte(char c)
13391 {
13392  return (unsigned int)((c >= '\\') ? c-36 : c-35);
13393 }
13394 NK_INTERN void
13395 nk_decode_85(unsigned char* dst, const unsigned char* src)
13396 {
13397  while (*src)
13398  {
13399  unsigned int tmp =
13400  nk_decode_85_byte((char)src[0]) +
13401  85 * (nk_decode_85_byte((char)src[1]) +
13402  85 * (nk_decode_85_byte((char)src[2]) +
13403  85 * (nk_decode_85_byte((char)src[3]) +
13404  85 * nk_decode_85_byte((char)src[4]))));
13405 
13406  /* we can't assume little-endianess. */
13407  dst[0] = (unsigned char)((tmp >> 0) & 0xFF);
13408  dst[1] = (unsigned char)((tmp >> 8) & 0xFF);
13409  dst[2] = (unsigned char)((tmp >> 16) & 0xFF);
13410  dst[3] = (unsigned char)((tmp >> 24) & 0xFF);
13411 
13412  src += 5;
13413  dst += 4;
13414  }
13415 }
13416 
13417 /* -------------------------------------------------------------
13418  *
13419  * FONT ATLAS
13420  *
13421  * --------------------------------------------------------------*/
13422 NK_API struct nk_font_config
13423 nk_font_config(float pixel_height)
13424 {
13425  struct nk_font_config cfg;
13426  nk_zero_struct(cfg);
13427  cfg.ttf_blob = 0;
13428  cfg.ttf_size = 0;
13429  cfg.ttf_data_owned_by_atlas = 0;
13430  cfg.size = pixel_height;
13431  cfg.oversample_h = 3;
13432  cfg.oversample_v = 1;
13433  cfg.pixel_snap = 0;
13434  cfg.coord_type = NK_COORD_UV;
13435  cfg.spacing = nk_vec2(0,0);
13436  cfg.range = nk_font_default_glyph_ranges();
13437  cfg.merge_mode = 0;
13438  cfg.fallback_glyph = '?';
13439  cfg.font = 0;
13440  cfg.n = 0;
13441  return cfg;
13442 }
13443 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
13444 NK_API void
13445 nk_font_atlas_init_default(struct nk_font_atlas *atlas)
13446 {
13447  NK_ASSERT(atlas);
13448  if (!atlas) return;
13449  nk_zero_struct(*atlas);
13450  atlas->temporary.userdata.ptr = 0;
13451  atlas->temporary.alloc = nk_malloc;
13452  atlas->temporary.free = nk_mfree;
13453  atlas->permanent.userdata.ptr = 0;
13454  atlas->permanent.alloc = nk_malloc;
13455  atlas->permanent.free = nk_mfree;
13456 }
13457 #endif
13458 NK_API void
13459 nk_font_atlas_init(struct nk_font_atlas *atlas, struct nk_allocator *alloc)
13460 {
13461  NK_ASSERT(atlas);
13462  NK_ASSERT(alloc);
13463  if (!atlas || !alloc) return;
13464  nk_zero_struct(*atlas);
13465  atlas->permanent = *alloc;
13466  atlas->temporary = *alloc;
13467 }
13468 NK_API void
13469 nk_font_atlas_init_custom(struct nk_font_atlas *atlas,
13470  struct nk_allocator *permanent, struct nk_allocator *temporary)
13471 {
13472  NK_ASSERT(atlas);
13473  NK_ASSERT(permanent);
13474  NK_ASSERT(temporary);
13475  if (!atlas || !permanent || !temporary) return;
13476  nk_zero_struct(*atlas);
13477  atlas->permanent = *permanent;
13478  atlas->temporary = *temporary;
13479 }
13480 NK_API void
13481 nk_font_atlas_begin(struct nk_font_atlas *atlas)
13482 {
13483  NK_ASSERT(atlas);
13484  NK_ASSERT(atlas->temporary.alloc && atlas->temporary.free);
13485  NK_ASSERT(atlas->permanent.alloc && atlas->permanent.free);
13486  if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free ||
13487  !atlas->temporary.alloc || !atlas->temporary.free) return;
13488  if (atlas->glyphs) {
13489  atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
13490  atlas->glyphs = 0;
13491  }
13492  if (atlas->pixel) {
13493  atlas->permanent.free(atlas->permanent.userdata, atlas->pixel);
13494  atlas->pixel = 0;
13495  }
13496 }
13497 NK_API struct nk_font*
13498 nk_font_atlas_add(struct nk_font_atlas *atlas, const struct nk_font_config *config)
13499 {
13500  struct nk_font *font = 0;
13501  struct nk_font_config *cfg;
13502 
13503  NK_ASSERT(atlas);
13504  NK_ASSERT(atlas->permanent.alloc);
13505  NK_ASSERT(atlas->permanent.free);
13506  NK_ASSERT(atlas->temporary.alloc);
13507  NK_ASSERT(atlas->temporary.free);
13508 
13509  NK_ASSERT(config);
13510  NK_ASSERT(config->ttf_blob);
13511  NK_ASSERT(config->ttf_size);
13512  NK_ASSERT(config->size > 0.0f);
13513 
13514  if (!atlas || !config || !config->ttf_blob || !config->ttf_size || config->size <= 0.0f||
13515  !atlas->permanent.alloc || !atlas->permanent.free ||
13516  !atlas->temporary.alloc || !atlas->temporary.free)
13517  return 0;
13518 
13519  /* allocate font config */
13520  cfg = (struct nk_font_config*)
13521  atlas->permanent.alloc(atlas->permanent.userdata,0, sizeof(struct nk_font_config));
13522  NK_MEMCPY(cfg, config, sizeof(*config));
13523  cfg->n = cfg;
13524  cfg->p = cfg;
13525 
13526  if (!config->merge_mode) {
13527  /* insert font config into list */
13528  if (!atlas->config) {
13529  atlas->config = cfg;
13530  cfg->next = 0;
13531  } else {
13532  struct nk_font_config *i = atlas->config;
13533  while (i->next) i = i->next;
13534  i->next = cfg;
13535  cfg->next = 0;
13536  }
13537  /* allocate new font */
13538  font = (struct nk_font*)
13539  atlas->permanent.alloc(atlas->permanent.userdata,0, sizeof(struct nk_font));
13540  NK_ASSERT(font);
13541  nk_zero(font, sizeof(*font));
13542  if (!font) return 0;
13543  font->config = cfg;
13544 
13545  /* insert font into list */
13546  if (!atlas->fonts) {
13547  atlas->fonts = font;
13548  font->next = 0;
13549  } else {
13550  struct nk_font *i = atlas->fonts;
13551  while (i->next) i = i->next;
13552  i->next = font;
13553  font->next = 0;
13554  }
13555  cfg->font = &font->info;
13556  } else {
13557  /* extend previously added font */
13558  struct nk_font *f = 0;
13559  struct nk_font_config *c = 0;
13560  NK_ASSERT(atlas->font_num);
13561  f = atlas->fonts;
13562  c = f->config;
13563  cfg->font = &f->info;
13564 
13565  cfg->n = c;
13566  cfg->p = c->p;
13567  c->p->n = cfg;
13568  c->p = cfg;
13569  }
13570  /* create own copy of .TTF font blob */
13571  if (!config->ttf_data_owned_by_atlas) {
13572  cfg->ttf_blob = atlas->permanent.alloc(atlas->permanent.userdata,0, cfg->ttf_size);
13573  NK_ASSERT(cfg->ttf_blob);
13574  if (!cfg->ttf_blob) {
13575  atlas->font_num++;
13576  return 0;
13577  }
13578  NK_MEMCPY(cfg->ttf_blob, config->ttf_blob, cfg->ttf_size);
13579  cfg->ttf_data_owned_by_atlas = 1;
13580  }
13581  atlas->font_num++;
13582  return font;
13583 }
13584 NK_API struct nk_font*
13585 nk_font_atlas_add_from_memory(struct nk_font_atlas *atlas, void *memory,
13586  nk_size size, float height, const struct nk_font_config *config)
13587 {
13588  struct nk_font_config cfg;
13589  NK_ASSERT(memory);
13590  NK_ASSERT(size);
13591 
13592  NK_ASSERT(atlas);
13593  NK_ASSERT(atlas->temporary.alloc);
13594  NK_ASSERT(atlas->temporary.free);
13595  NK_ASSERT(atlas->permanent.alloc);
13596  NK_ASSERT(atlas->permanent.free);
13597  if (!atlas || !atlas->temporary.alloc || !atlas->temporary.free || !memory || !size ||
13598  !atlas->permanent.alloc || !atlas->permanent.free)
13599  return 0;
13600 
13601  cfg = (config) ? *config: nk_font_config(height);
13602  cfg.ttf_blob = memory;
13603  cfg.ttf_size = size;
13604  cfg.size = height;
13605  cfg.ttf_data_owned_by_atlas = 0;
13606  return nk_font_atlas_add(atlas, &cfg);
13607 }
13608 #ifdef NK_INCLUDE_STANDARD_IO
13609 NK_API struct nk_font*
13610 nk_font_atlas_add_from_file(struct nk_font_atlas *atlas, const char *file_path,
13611  float height, const struct nk_font_config *config)
13612 {
13613  nk_size size;
13614  char *memory;
13615  struct nk_font_config cfg;
13616 
13617  NK_ASSERT(atlas);
13618  NK_ASSERT(atlas->temporary.alloc);
13619  NK_ASSERT(atlas->temporary.free);
13620  NK_ASSERT(atlas->permanent.alloc);
13621  NK_ASSERT(atlas->permanent.free);
13622 
13623  if (!atlas || !file_path) return 0;
13624  memory = nk_file_load(file_path, &size, &atlas->permanent);
13625  if (!memory) return 0;
13626 
13627  cfg = (config) ? *config: nk_font_config(height);
13628  cfg.ttf_blob = memory;
13629  cfg.ttf_size = size;
13630  cfg.size = height;
13631  cfg.ttf_data_owned_by_atlas = 1;
13632  return nk_font_atlas_add(atlas, &cfg);
13633 }
13634 #endif
13635 NK_API struct nk_font*
13636 nk_font_atlas_add_compressed(struct nk_font_atlas *atlas,
13637  void *compressed_data, nk_size compressed_size, float height,
13638  const struct nk_font_config *config)
13639 {
13640  unsigned int decompressed_size;
13641  void *decompressed_data;
13642  struct nk_font_config cfg;
13643 
13644  NK_ASSERT(atlas);
13645  NK_ASSERT(atlas->temporary.alloc);
13646  NK_ASSERT(atlas->temporary.free);
13647  NK_ASSERT(atlas->permanent.alloc);
13648  NK_ASSERT(atlas->permanent.free);
13649 
13650  NK_ASSERT(compressed_data);
13651  NK_ASSERT(compressed_size);
13652  if (!atlas || !compressed_data || !atlas->temporary.alloc || !atlas->temporary.free ||
13653  !atlas->permanent.alloc || !atlas->permanent.free)
13654  return 0;
13655 
13656  decompressed_size = nk_decompress_length((unsigned char*)compressed_data);
13657  decompressed_data = atlas->permanent.alloc(atlas->permanent.userdata,0,decompressed_size);
13658  NK_ASSERT(decompressed_data);
13659  if (!decompressed_data) return 0;
13660  nk_decompress((unsigned char*)decompressed_data, (unsigned char*)compressed_data,
13661  (unsigned int)compressed_size);
13662 
13663  cfg = (config) ? *config: nk_font_config(height);
13664  cfg.ttf_blob = decompressed_data;
13665  cfg.ttf_size = decompressed_size;
13666  cfg.size = height;
13667  cfg.ttf_data_owned_by_atlas = 1;
13668  return nk_font_atlas_add(atlas, &cfg);
13669 }
13670 NK_API struct nk_font*
13671 nk_font_atlas_add_compressed_base85(struct nk_font_atlas *atlas,
13672  const char *data_base85, float height, const struct nk_font_config *config)
13673 {
13674  int compressed_size;
13675  void *compressed_data;
13676  struct nk_font *font;
13677 
13678  NK_ASSERT(atlas);
13679  NK_ASSERT(atlas->temporary.alloc);
13680  NK_ASSERT(atlas->temporary.free);
13681  NK_ASSERT(atlas->permanent.alloc);
13682  NK_ASSERT(atlas->permanent.free);
13683 
13684  NK_ASSERT(data_base85);
13685  if (!atlas || !data_base85 || !atlas->temporary.alloc || !atlas->temporary.free ||
13686  !atlas->permanent.alloc || !atlas->permanent.free)
13687  return 0;
13688 
13689  compressed_size = (((int)nk_strlen(data_base85) + 4) / 5) * 4;
13690  compressed_data = atlas->temporary.alloc(atlas->temporary.userdata,0, (nk_size)compressed_size);
13691  NK_ASSERT(compressed_data);
13692  if (!compressed_data) return 0;
13693  nk_decode_85((unsigned char*)compressed_data, (const unsigned char*)data_base85);
13694  font = nk_font_atlas_add_compressed(atlas, compressed_data,
13695  (nk_size)compressed_size, height, config);
13696  atlas->temporary.free(atlas->temporary.userdata, compressed_data);
13697  return font;
13698 }
13699 
13700 #ifdef NK_INCLUDE_DEFAULT_FONT
13701 NK_API struct nk_font*
13702 nk_font_atlas_add_default(struct nk_font_atlas *atlas,
13703  float pixel_height, const struct nk_font_config *config)
13704 {
13705  NK_ASSERT(atlas);
13706  NK_ASSERT(atlas->temporary.alloc);
13707  NK_ASSERT(atlas->temporary.free);
13708  NK_ASSERT(atlas->permanent.alloc);
13709  NK_ASSERT(atlas->permanent.free);
13710  return nk_font_atlas_add_compressed_base85(atlas,
13711  nk_proggy_clean_ttf_compressed_data_base85, pixel_height, config);
13712 }
13713 #endif
13714 NK_API const void*
13715 nk_font_atlas_bake(struct nk_font_atlas *atlas, int *width, int *height,
13716  enum nk_font_atlas_format fmt)
13717 {
13718  int i = 0;
13719  void *tmp = 0;
13720  nk_size tmp_size, img_size;
13721  struct nk_font *font_iter;
13722  struct nk_font_baker *baker;
13723 
13724  NK_ASSERT(atlas);
13725  NK_ASSERT(atlas->temporary.alloc);
13726  NK_ASSERT(atlas->temporary.free);
13727  NK_ASSERT(atlas->permanent.alloc);
13728  NK_ASSERT(atlas->permanent.free);
13729 
13730  NK_ASSERT(width);
13731  NK_ASSERT(height);
13732  if (!atlas || !width || !height ||
13733  !atlas->temporary.alloc || !atlas->temporary.free ||
13734  !atlas->permanent.alloc || !atlas->permanent.free)
13735  return 0;
13736 
13737 #ifdef NK_INCLUDE_DEFAULT_FONT
13738  /* no font added so just use default font */
13739  if (!atlas->font_num)
13740  atlas->default_font = nk_font_atlas_add_default(atlas, 13.0f, 0);
13741 #endif
13742  NK_ASSERT(atlas->font_num);
13743  if (!atlas->font_num) return 0;
13744 
13745  /* allocate temporary baker memory required for the baking process */
13746  nk_font_baker_memory(&tmp_size, &atlas->glyph_count, atlas->config, atlas->font_num);
13747  tmp = atlas->temporary.alloc(atlas->temporary.userdata,0, tmp_size);
13748  NK_ASSERT(tmp);
13749  if (!tmp) goto failed;
13750 
13751  /* allocate glyph memory for all fonts */
13752  baker = nk_font_baker(tmp, atlas->glyph_count, atlas->font_num, &atlas->temporary);
13753  atlas->glyphs = (struct nk_font_glyph*)atlas->permanent.alloc(
13754  atlas->permanent.userdata,0, sizeof(struct nk_font_glyph)*(nk_size)atlas->glyph_count);
13755  NK_ASSERT(atlas->glyphs);
13756  if (!atlas->glyphs)
13757  goto failed;
13758 
13759  /* pack all glyphs into a tight fit space */
13760  atlas->custom.w = (NK_CURSOR_DATA_W*2)+1;
13761  atlas->custom.h = NK_CURSOR_DATA_H + 1;
13762  if (!nk_font_bake_pack(baker, &img_size, width, height, &atlas->custom,
13763  atlas->config, atlas->font_num, &atlas->temporary))
13764  goto failed;
13765 
13766  /* allocate memory for the baked image font atlas */
13767  atlas->pixel = atlas->temporary.alloc(atlas->temporary.userdata,0, img_size);
13768  NK_ASSERT(atlas->pixel);
13769  if (!atlas->pixel)
13770  goto failed;
13771 
13772  /* bake glyphs and custom white pixel into image */
13773  nk_font_bake(baker, atlas->pixel, *width, *height,
13774  atlas->glyphs, atlas->glyph_count, atlas->config, atlas->font_num);
13775  nk_font_bake_custom_data(atlas->pixel, *width, *height, atlas->custom,
13776  nk_custom_cursor_data, NK_CURSOR_DATA_W, NK_CURSOR_DATA_H, '.', 'X');
13777 
13778  if (fmt == NK_FONT_ATLAS_RGBA32) {
13779  /* convert alpha8 image into rgba32 image */
13780  void *img_rgba = atlas->temporary.alloc(atlas->temporary.userdata,0,
13781  (nk_size)(*width * *height * 4));
13782  NK_ASSERT(img_rgba);
13783  if (!img_rgba) goto failed;
13784  nk_font_bake_convert(img_rgba, *width, *height, atlas->pixel);
13785  atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
13786  atlas->pixel = img_rgba;
13787  }
13788  atlas->tex_width = *width;
13789  atlas->tex_height = *height;
13790 
13791  /* initialize each font */
13792  for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) {
13793  struct nk_font *font = font_iter;
13794  struct nk_font_config *config = font->config;
13795  nk_font_init(font, config->size, config->fallback_glyph, atlas->glyphs,
13796  config->font, nk_handle_ptr(0));
13797  }
13798 
13799  /* initialize each cursor */
13800  {NK_STORAGE const struct nk_vec2 nk_cursor_data[NK_CURSOR_COUNT][3] = {
13801  /* Pos Size Offset */
13802  {{ 0, 3}, {12,19}, { 0, 0}},
13803  {{13, 0}, { 7,16}, { 4, 8}},
13804  {{31, 0}, {23,23}, {11,11}},
13805  {{21, 0}, { 9, 23}, { 5,11}},
13806  {{55,18}, {23, 9}, {11, 5}},
13807  {{73, 0}, {17,17}, { 9, 9}},
13808  {{55, 0}, {17,17}, { 9, 9}}
13809  };
13810  for (i = 0; i < NK_CURSOR_COUNT; ++i) {
13811  struct nk_cursor *cursor = &atlas->cursors[i];
13812  cursor->img.w = (unsigned short)*width;
13813  cursor->img.h = (unsigned short)*height;
13814  cursor->img.region[0] = (unsigned short)(atlas->custom.x + nk_cursor_data[i][0].x);
13815  cursor->img.region[1] = (unsigned short)(atlas->custom.y + nk_cursor_data[i][0].y);
13816  cursor->img.region[2] = (unsigned short)nk_cursor_data[i][1].x;
13817  cursor->img.region[3] = (unsigned short)nk_cursor_data[i][1].y;
13818  cursor->size = nk_cursor_data[i][1];
13819  cursor->offset = nk_cursor_data[i][2];
13820  }}
13821  /* free temporary memory */
13822  atlas->temporary.free(atlas->temporary.userdata, tmp);
13823  return atlas->pixel;
13824 
13825 failed:
13826  /* error so cleanup all memory */
13827  if (tmp) atlas->temporary.free(atlas->temporary.userdata, tmp);
13828  if (atlas->glyphs) {
13829  atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
13830  atlas->glyphs = 0;
13831  }
13832  if (atlas->pixel) {
13833  atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
13834  atlas->pixel = 0;
13835  }
13836  return 0;
13837 }
13838 NK_API void
13839 nk_font_atlas_end(struct nk_font_atlas *atlas, nk_handle texture,
13840  struct nk_draw_null_texture *null)
13841 {
13842  int i = 0;
13843  struct nk_font *font_iter;
13844  NK_ASSERT(atlas);
13845  if (!atlas) {
13846  if (!null) return;
13847  null->texture = texture;
13848  null->uv = nk_vec2(0.5f,0.5f);
13849  }
13850  if (null) {
13851  null->texture = texture;
13852  null->uv.x = (atlas->custom.x + 0.5f)/(float)atlas->tex_width;
13853  null->uv.y = (atlas->custom.y + 0.5f)/(float)atlas->tex_height;
13854  }
13855  for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) {
13856  font_iter->texture = texture;
13857 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
13858  font_iter->handle.texture = texture;
13859 #endif
13860  }
13861  for (i = 0; i < NK_CURSOR_COUNT; ++i)
13862  atlas->cursors[i].img.handle = texture;
13863 
13864  atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
13865  atlas->pixel = 0;
13866  atlas->tex_width = 0;
13867  atlas->tex_height = 0;
13868  atlas->custom.x = 0;
13869  atlas->custom.y = 0;
13870  atlas->custom.w = 0;
13871  atlas->custom.h = 0;
13872 }
13873 NK_API void
13874 nk_font_atlas_cleanup(struct nk_font_atlas *atlas)
13875 {
13876  NK_ASSERT(atlas);
13877  NK_ASSERT(atlas->temporary.alloc);
13878  NK_ASSERT(atlas->temporary.free);
13879  NK_ASSERT(atlas->permanent.alloc);
13880  NK_ASSERT(atlas->permanent.free);
13881  if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free) return;
13882  if (atlas->config) {
13883  struct nk_font_config *iter;
13884  for (iter = atlas->config; iter; iter = iter->next) {
13885  struct nk_font_config *i;
13886  for (i = iter->n; i != iter; i = i->n) {
13887  atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob);
13888  i->ttf_blob = 0;
13889  }
13890  atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob);
13891  iter->ttf_blob = 0;
13892  }
13893  }
13894 }
13895 NK_API void
13896 nk_font_atlas_clear(struct nk_font_atlas *atlas)
13897 {
13898  NK_ASSERT(atlas);
13899  NK_ASSERT(atlas->temporary.alloc);
13900  NK_ASSERT(atlas->temporary.free);
13901  NK_ASSERT(atlas->permanent.alloc);
13902  NK_ASSERT(atlas->permanent.free);
13903  if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free) return;
13904 
13905  if (atlas->config) {
13906  struct nk_font_config *iter, *next;
13907  for (iter = atlas->config; iter; iter = next) {
13908  struct nk_font_config *i, *n;
13909  for (i = iter->n; i != iter; i = n) {
13910  n = i->n;
13911  if (i->ttf_blob)
13912  atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob);
13913  atlas->permanent.free(atlas->permanent.userdata, i);
13914  }
13915  next = iter->next;
13916  if (i->ttf_blob)
13917  atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob);
13918  atlas->permanent.free(atlas->permanent.userdata, iter);
13919  }
13920  atlas->config = 0;
13921  }
13922  if (atlas->fonts) {
13923  struct nk_font *iter, *next;
13924  for (iter = atlas->fonts; iter; iter = next) {
13925  next = iter->next;
13926  atlas->permanent.free(atlas->permanent.userdata, iter);
13927  }
13928  atlas->fonts = 0;
13929  }
13930  if (atlas->glyphs)
13931  atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
13932  nk_zero_struct(*atlas);
13933 }
13934 #endif
13935 
13936 
13937 
13938 
13939 
13940 /* ===============================================================
13941  *
13942  * INPUT
13943  *
13944  * ===============================================================*/
13945 NK_API void
13946 nk_input_begin(struct nk_context *ctx)
13947 {
13948  int i;
13949  struct nk_input *in;
13950  NK_ASSERT(ctx);
13951  if (!ctx) return;
13952  in = &ctx->input;
13953  for (i = 0; i < NK_BUTTON_MAX; ++i)
13954  in->mouse.buttons[i].clicked = 0;
13955 
13956  in->keyboard.text_len = 0;
13957  in->mouse.scroll_delta = nk_vec2(0,0);
13958  in->mouse.prev.x = in->mouse.pos.x;
13959  in->mouse.prev.y = in->mouse.pos.y;
13960  in->mouse.delta.x = 0;
13961  in->mouse.delta.y = 0;
13962  for (i = 0; i < NK_KEY_MAX; i++)
13963  in->keyboard.keys[i].clicked = 0;
13964 }
13965 NK_API void
13966 nk_input_end(struct nk_context *ctx)
13967 {
13968  struct nk_input *in;
13969  NK_ASSERT(ctx);
13970  if (!ctx) return;
13971  in = &ctx->input;
13972  if (in->mouse.grab)
13973  in->mouse.grab = 0;
13974  if (in->mouse.ungrab) {
13975  in->mouse.grabbed = 0;
13976  in->mouse.ungrab = 0;
13977  in->mouse.grab = 0;
13978  }
13979 }
13980 NK_API void
13981 nk_input_motion(struct nk_context *ctx, int x, int y)
13982 {
13983  struct nk_input *in;
13984  NK_ASSERT(ctx);
13985  if (!ctx) return;
13986  in = &ctx->input;
13987  in->mouse.pos.x = (float)x;
13988  in->mouse.pos.y = (float)y;
13989  in->mouse.delta.x = in->mouse.pos.x - in->mouse.prev.x;
13990  in->mouse.delta.y = in->mouse.pos.y - in->mouse.prev.y;
13991 }
13992 NK_API void
13993 nk_input_key(struct nk_context *ctx, enum nk_keys key, int down)
13994 {
13995  struct nk_input *in;
13996  NK_ASSERT(ctx);
13997  if (!ctx) return;
13998  in = &ctx->input;
13999 #ifdef NK_KEYSTATE_BASED_INPUT
14000  if (in->keyboard.keys[key].down != down)
14001  in->keyboard.keys[key].clicked++;
14002 #else
14003  in->keyboard.keys[key].clicked++;
14004 #endif
14005  in->keyboard.keys[key].down = down;
14006 }
14007 NK_API void
14008 nk_input_button(struct nk_context *ctx, enum nk_buttons id, int x, int y, int down)
14009 {
14010  struct nk_mouse_button *btn;
14011  struct nk_input *in;
14012  NK_ASSERT(ctx);
14013  if (!ctx) return;
14014  in = &ctx->input;
14015  if (in->mouse.buttons[id].down == down) return;
14016 
14017  btn = &in->mouse.buttons[id];
14018  btn->clicked_pos.x = (float)x;
14019  btn->clicked_pos.y = (float)y;
14020  btn->down = down;
14021  btn->clicked++;
14022 }
14023 NK_API void
14024 nk_input_scroll(struct nk_context *ctx, struct nk_vec2 val)
14025 {
14026  NK_ASSERT(ctx);
14027  if (!ctx) return;
14028  ctx->input.mouse.scroll_delta.x += val.x;
14029  ctx->input.mouse.scroll_delta.y += val.y;
14030 }
14031 NK_API void
14032 nk_input_glyph(struct nk_context *ctx, const nk_glyph glyph)
14033 {
14034  int len = 0;
14035  nk_rune unicode;
14036  struct nk_input *in;
14037 
14038  NK_ASSERT(ctx);
14039  if (!ctx) return;
14040  in = &ctx->input;
14041 
14042  len = nk_utf_decode(glyph, &unicode, NK_UTF_SIZE);
14043  if (len && ((in->keyboard.text_len + len) < NK_INPUT_MAX)) {
14044  nk_utf_encode(unicode, &in->keyboard.text[in->keyboard.text_len],
14046  in->keyboard.text_len += len;
14047  }
14048 }
14049 NK_API void
14050 nk_input_char(struct nk_context *ctx, char c)
14051 {
14052  nk_glyph glyph;
14053  NK_ASSERT(ctx);
14054  if (!ctx) return;
14055  glyph[0] = c;
14056  nk_input_glyph(ctx, glyph);
14057 }
14058 NK_API void
14059 nk_input_unicode(struct nk_context *ctx, nk_rune unicode)
14060 {
14061  nk_glyph rune;
14062  NK_ASSERT(ctx);
14063  if (!ctx) return;
14064  nk_utf_encode(unicode, rune, NK_UTF_SIZE);
14065  nk_input_glyph(ctx, rune);
14066 }
14067 NK_API int
14068 nk_input_has_mouse_click(const struct nk_input *i, enum nk_buttons id)
14069 {
14070  const struct nk_mouse_button *btn;
14071  if (!i) return nk_false;
14072  btn = &i->mouse.buttons[id];
14073  return (btn->clicked && btn->down == nk_false) ? nk_true : nk_false;
14074 }
14075 NK_API int
14076 nk_input_has_mouse_click_in_rect(const struct nk_input *i, enum nk_buttons id,
14077  struct nk_rect b)
14078 {
14079  const struct nk_mouse_button *btn;
14080  if (!i) return nk_false;
14081  btn = &i->mouse.buttons[id];
14082  if (!NK_INBOX(btn->clicked_pos.x,btn->clicked_pos.y,b.x,b.y,b.w,b.h))
14083  return nk_false;
14084  return nk_true;
14085 }
14086 NK_API int
14088  struct nk_rect b, int down)
14089 {
14090  const struct nk_mouse_button *btn;
14091  if (!i) return nk_false;
14092  btn = &i->mouse.buttons[id];
14093  return nk_input_has_mouse_click_in_rect(i, id, b) && (btn->down == down);
14094 }
14095 NK_API int
14096 nk_input_is_mouse_click_in_rect(const struct nk_input *i, enum nk_buttons id,
14097  struct nk_rect b)
14098 {
14099  const struct nk_mouse_button *btn;
14100  if (!i) return nk_false;
14101  btn = &i->mouse.buttons[id];
14102  return (nk_input_has_mouse_click_down_in_rect(i, id, b, nk_false) &&
14103  btn->clicked) ? nk_true : nk_false;
14104 }
14105 NK_API int
14107  struct nk_rect b, int down)
14108 {
14109  const struct nk_mouse_button *btn;
14110  if (!i) return nk_false;
14111  btn = &i->mouse.buttons[id];
14112  return (nk_input_has_mouse_click_down_in_rect(i, id, b, down) &&
14113  btn->clicked) ? nk_true : nk_false;
14114 }
14115 NK_API int
14116 nk_input_any_mouse_click_in_rect(const struct nk_input *in, struct nk_rect b)
14117 {
14118  int i, down = 0;
14119  for (i = 0; i < NK_BUTTON_MAX; ++i)
14120  down = down || nk_input_is_mouse_click_in_rect(in, (enum nk_buttons)i, b);
14121  return down;
14122 }
14123 NK_API int
14124 nk_input_is_mouse_hovering_rect(const struct nk_input *i, struct nk_rect rect)
14125 {
14126  if (!i) return nk_false;
14127  return NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, rect.x, rect.y, rect.w, rect.h);
14128 }
14129 NK_API int
14130 nk_input_is_mouse_prev_hovering_rect(const struct nk_input *i, struct nk_rect rect)
14131 {
14132  if (!i) return nk_false;
14133  return NK_INBOX(i->mouse.prev.x, i->mouse.prev.y, rect.x, rect.y, rect.w, rect.h);
14134 }
14135 NK_API int
14136 nk_input_mouse_clicked(const struct nk_input *i, enum nk_buttons id, struct nk_rect rect)
14137 {
14138  if (!i) return nk_false;
14139  if (!nk_input_is_mouse_hovering_rect(i, rect)) return nk_false;
14140  return nk_input_is_mouse_click_in_rect(i, id, rect);
14141 }
14142 NK_API int
14143 nk_input_is_mouse_down(const struct nk_input *i, enum nk_buttons id)
14144 {
14145  if (!i) return nk_false;
14146  return i->mouse.buttons[id].down;
14147 }
14148 NK_API int
14149 nk_input_is_mouse_pressed(const struct nk_input *i, enum nk_buttons id)
14150 {
14151  const struct nk_mouse_button *b;
14152  if (!i) return nk_false;
14153  b = &i->mouse.buttons[id];
14154  if (b->down && b->clicked)
14155  return nk_true;
14156  return nk_false;
14157 }
14158 NK_API int
14159 nk_input_is_mouse_released(const struct nk_input *i, enum nk_buttons id)
14160 {
14161  if (!i) return nk_false;
14162  return (!i->mouse.buttons[id].down && i->mouse.buttons[id].clicked);
14163 }
14164 NK_API int
14165 nk_input_is_key_pressed(const struct nk_input *i, enum nk_keys key)
14166 {
14167  const struct nk_key *k;
14168  if (!i) return nk_false;
14169  k = &i->keyboard.keys[key];
14170  if ((k->down && k->clicked) || (!k->down && k->clicked >= 2))
14171  return nk_true;
14172  return nk_false;
14173 }
14174 NK_API int
14175 nk_input_is_key_released(const struct nk_input *i, enum nk_keys key)
14176 {
14177  const struct nk_key *k;
14178  if (!i) return nk_false;
14179  k = &i->keyboard.keys[key];
14180  if ((!k->down && k->clicked) || (k->down && k->clicked >= 2))
14181  return nk_true;
14182  return nk_false;
14183 }
14184 NK_API int
14185 nk_input_is_key_down(const struct nk_input *i, enum nk_keys key)
14186 {
14187  const struct nk_key *k;
14188  if (!i) return nk_false;
14189  k = &i->keyboard.keys[key];
14190  if (k->down) return nk_true;
14191  return nk_false;
14192 }
14193 
14194 
14195 
14196 
14197 
14198 /* ===============================================================
14199  *
14200  * STYLE
14201  *
14202  * ===============================================================*/
14204 #define NK_COLOR_MAP(NK_COLOR)\
14205  NK_COLOR(NK_COLOR_TEXT, 175,175,175,255) \
14206  NK_COLOR(NK_COLOR_WINDOW, 45, 45, 45, 255) \
14207  NK_COLOR(NK_COLOR_HEADER, 40, 40, 40, 255) \
14208  NK_COLOR(NK_COLOR_BORDER, 65, 65, 65, 255) \
14209  NK_COLOR(NK_COLOR_BUTTON, 50, 50, 50, 255) \
14210  NK_COLOR(NK_COLOR_BUTTON_HOVER, 40, 40, 40, 255) \
14211  NK_COLOR(NK_COLOR_BUTTON_ACTIVE, 35, 35, 35, 255) \
14212  NK_COLOR(NK_COLOR_TOGGLE, 100,100,100,255) \
14213  NK_COLOR(NK_COLOR_TOGGLE_HOVER, 120,120,120,255) \
14214  NK_COLOR(NK_COLOR_TOGGLE_CURSOR, 45, 45, 45, 255) \
14215  NK_COLOR(NK_COLOR_SELECT, 45, 45, 45, 255) \
14216  NK_COLOR(NK_COLOR_SELECT_ACTIVE, 35, 35, 35,255) \
14217  NK_COLOR(NK_COLOR_SLIDER, 38, 38, 38, 255) \
14218  NK_COLOR(NK_COLOR_SLIDER_CURSOR, 100,100,100,255) \
14219  NK_COLOR(NK_COLOR_SLIDER_CURSOR_HOVER, 120,120,120,255) \
14220  NK_COLOR(NK_COLOR_SLIDER_CURSOR_ACTIVE, 150,150,150,255) \
14221  NK_COLOR(NK_COLOR_PROPERTY, 38, 38, 38, 255) \
14222  NK_COLOR(NK_COLOR_EDIT, 38, 38, 38, 255) \
14223  NK_COLOR(NK_COLOR_EDIT_CURSOR, 175,175,175,255) \
14224  NK_COLOR(NK_COLOR_COMBO, 45, 45, 45, 255) \
14225  NK_COLOR(NK_COLOR_CHART, 120,120,120,255) \
14226  NK_COLOR(NK_COLOR_CHART_COLOR, 45, 45, 45, 255) \
14227  NK_COLOR(NK_COLOR_CHART_COLOR_HIGHLIGHT, 255, 0, 0, 255) \
14228  NK_COLOR(NK_COLOR_SCROLLBAR, 40, 40, 40, 255) \
14229  NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR, 100,100,100,255) \
14230  NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_HOVER, 120,120,120,255) \
14231  NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_ACTIVE, 150,150,150,255) \
14232  NK_COLOR(NK_COLOR_TAB_HEADER, 40, 40, 40,255)
14233 
14234 NK_GLOBAL const struct nk_color
14235 nk_default_color_style[NK_COLOR_COUNT] = {
14236 #define NK_COLOR(a,b,c,d,e) {b,c,d,e},
14237  NK_COLOR_MAP(NK_COLOR)
14238 #undef NK_COLOR
14239 };
14240 NK_GLOBAL const char *nk_color_names[NK_COLOR_COUNT] = {
14241 #define NK_COLOR(a,b,c,d,e) #a,
14242  NK_COLOR_MAP(NK_COLOR)
14243 #undef NK_COLOR
14244 };
14245 
14246 NK_API const char*
14248 {
14249  return nk_color_names[c];
14250 }
14251 NK_API struct nk_style_item
14252 nk_style_item_image(struct nk_image img)
14253 {
14254  struct nk_style_item i;
14255  i.type = NK_STYLE_ITEM_IMAGE;
14256  i.data.image = img;
14257  return i;
14258 }
14259 NK_API struct nk_style_item
14260 nk_style_item_color(struct nk_color col)
14261 {
14262  struct nk_style_item i;
14263  i.type = NK_STYLE_ITEM_COLOR;
14264  i.data.color = col;
14265  return i;
14266 }
14267 NK_API struct nk_style_item
14268 nk_style_item_hide(void)
14269 {
14270  struct nk_style_item i;
14271  i.type = NK_STYLE_ITEM_COLOR;
14272  i.data.color = nk_rgba(0,0,0,0);
14273  return i;
14274 }
14275 NK_API void
14276 nk_style_from_table(struct nk_context *ctx, const struct nk_color *table)
14277 {
14278  struct nk_style *style;
14279  struct nk_style_text *text;
14280  struct nk_style_button *button;
14281  struct nk_style_toggle *toggle;
14282  struct nk_style_selectable *select;
14283  struct nk_style_slider *slider;
14284  struct nk_style_progress *prog;
14285  struct nk_style_scrollbar *scroll;
14286  struct nk_style_edit *edit;
14287  struct nk_style_property *property;
14288  struct nk_style_combo *combo;
14289  struct nk_style_chart *chart;
14290  struct nk_style_tab *tab;
14291  struct nk_style_window *win;
14292 
14293  NK_ASSERT(ctx);
14294  if (!ctx) return;
14295  style = &ctx->style;
14296  table = (!table) ? nk_default_color_style: table;
14297 
14298  /* default text */
14299  text = &style->text;
14300  text->color = table[NK_COLOR_TEXT];
14301  text->padding = nk_vec2(0,0);
14302 
14303  /* default button */
14304  button = &style->button;
14305  nk_zero_struct(*button);
14306  button->normal = nk_style_item_color(table[NK_COLOR_BUTTON]);
14309  button->border_color = table[NK_COLOR_BORDER];
14310  button->text_background = table[NK_COLOR_BUTTON];
14311  button->text_normal = table[NK_COLOR_TEXT];
14312  button->text_hover = table[NK_COLOR_TEXT];
14313  button->text_active = table[NK_COLOR_TEXT];
14314  button->padding = nk_vec2(2.0f,2.0f);
14315  button->image_padding = nk_vec2(0.0f,0.0f);
14316  button->touch_padding = nk_vec2(0.0f, 0.0f);
14317  button->userdata = nk_handle_ptr(0);
14318  button->text_alignment = NK_TEXT_CENTERED;
14319  button->border = 1.0f;
14320  button->rounding = 4.0f;
14321  button->draw_begin = 0;
14322  button->draw_end = 0;
14323 
14324  /* contextual button */
14325  button = &style->contextual_button;
14326  nk_zero_struct(*button);
14327  button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
14330  button->border_color = table[NK_COLOR_WINDOW];
14331  button->text_background = table[NK_COLOR_WINDOW];
14332  button->text_normal = table[NK_COLOR_TEXT];
14333  button->text_hover = table[NK_COLOR_TEXT];
14334  button->text_active = table[NK_COLOR_TEXT];
14335  button->padding = nk_vec2(2.0f,2.0f);
14336  button->touch_padding = nk_vec2(0.0f,0.0f);
14337  button->userdata = nk_handle_ptr(0);
14338  button->text_alignment = NK_TEXT_CENTERED;
14339  button->border = 0.0f;
14340  button->rounding = 0.0f;
14341  button->draw_begin = 0;
14342  button->draw_end = 0;
14343 
14344  /* menu button */
14345  button = &style->menu_button;
14346  nk_zero_struct(*button);
14347  button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
14348  button->hover = nk_style_item_color(table[NK_COLOR_WINDOW]);
14349  button->active = nk_style_item_color(table[NK_COLOR_WINDOW]);
14350  button->border_color = table[NK_COLOR_WINDOW];
14351  button->text_background = table[NK_COLOR_WINDOW];
14352  button->text_normal = table[NK_COLOR_TEXT];
14353  button->text_hover = table[NK_COLOR_TEXT];
14354  button->text_active = table[NK_COLOR_TEXT];
14355  button->padding = nk_vec2(2.0f,2.0f);
14356  button->touch_padding = nk_vec2(0.0f,0.0f);
14357  button->userdata = nk_handle_ptr(0);
14358  button->text_alignment = NK_TEXT_CENTERED;
14359  button->border = 0.0f;
14360  button->rounding = 1.0f;
14361  button->draw_begin = 0;
14362  button->draw_end = 0;
14363 
14364  /* checkbox toggle */
14365  toggle = &style->checkbox;
14366  nk_zero_struct(*toggle);
14367  toggle->normal = nk_style_item_color(table[NK_COLOR_TOGGLE]);
14372  toggle->userdata = nk_handle_ptr(0);
14373  toggle->text_background = table[NK_COLOR_WINDOW];
14374  toggle->text_normal = table[NK_COLOR_TEXT];
14375  toggle->text_hover = table[NK_COLOR_TEXT];
14376  toggle->text_active = table[NK_COLOR_TEXT];
14377  toggle->padding = nk_vec2(2.0f, 2.0f);
14378  toggle->touch_padding = nk_vec2(0,0);
14379  toggle->border_color = nk_rgba(0,0,0,0);
14380  toggle->border = 0.0f;
14381  toggle->spacing = 4;
14382 
14383  /* option toggle */
14384  toggle = &style->option;
14385  nk_zero_struct(*toggle);
14386  toggle->normal = nk_style_item_color(table[NK_COLOR_TOGGLE]);
14391  toggle->userdata = nk_handle_ptr(0);
14392  toggle->text_background = table[NK_COLOR_WINDOW];
14393  toggle->text_normal = table[NK_COLOR_TEXT];
14394  toggle->text_hover = table[NK_COLOR_TEXT];
14395  toggle->text_active = table[NK_COLOR_TEXT];
14396  toggle->padding = nk_vec2(3.0f, 3.0f);
14397  toggle->touch_padding = nk_vec2(0,0);
14398  toggle->border_color = nk_rgba(0,0,0,0);
14399  toggle->border = 0.0f;
14400  toggle->spacing = 4;
14401 
14402  /* selectable */
14403  select = &style->selectable;
14404  nk_zero_struct(*select);
14405  select->normal = nk_style_item_color(table[NK_COLOR_SELECT]);
14406  select->hover = nk_style_item_color(table[NK_COLOR_SELECT]);
14407  select->pressed = nk_style_item_color(table[NK_COLOR_SELECT]);
14411  select->text_normal = table[NK_COLOR_TEXT];
14412  select->text_hover = table[NK_COLOR_TEXT];
14413  select->text_pressed = table[NK_COLOR_TEXT];
14414  select->text_normal_active = table[NK_COLOR_TEXT];
14415  select->text_hover_active = table[NK_COLOR_TEXT];
14416  select->text_pressed_active = table[NK_COLOR_TEXT];
14417  select->padding = nk_vec2(2.0f,2.0f);
14418  select->image_padding = nk_vec2(2.0f,2.0f);
14419  select->touch_padding = nk_vec2(0,0);
14420  select->userdata = nk_handle_ptr(0);
14421  select->rounding = 0.0f;
14422  select->draw_begin = 0;
14423  select->draw_end = 0;
14424 
14425  /* slider */
14426  slider = &style->slider;
14427  nk_zero_struct(*slider);
14428  slider->normal = nk_style_item_hide();
14429  slider->hover = nk_style_item_hide();
14430  slider->active = nk_style_item_hide();
14431  slider->bar_normal = table[NK_COLOR_SLIDER];
14432  slider->bar_hover = table[NK_COLOR_SLIDER];
14433  slider->bar_active = table[NK_COLOR_SLIDER];
14434  slider->bar_filled = table[NK_COLOR_SLIDER_CURSOR];
14440  slider->cursor_size = nk_vec2(16,16);
14441  slider->padding = nk_vec2(2,2);
14442  slider->spacing = nk_vec2(2,2);
14443  slider->userdata = nk_handle_ptr(0);
14444  slider->show_buttons = nk_false;
14445  slider->bar_height = 8;
14446  slider->rounding = 0;
14447  slider->draw_begin = 0;
14448  slider->draw_end = 0;
14449 
14450  /* slider buttons */
14451  button = &style->slider.inc_button;
14452  button->normal = nk_style_item_color(nk_rgb(40,40,40));
14453  button->hover = nk_style_item_color(nk_rgb(42,42,42));
14454  button->active = nk_style_item_color(nk_rgb(44,44,44));
14455  button->border_color = nk_rgb(65,65,65);
14456  button->text_background = nk_rgb(40,40,40);
14457  button->text_normal = nk_rgb(175,175,175);
14458  button->text_hover = nk_rgb(175,175,175);
14459  button->text_active = nk_rgb(175,175,175);
14460  button->padding = nk_vec2(8.0f,8.0f);
14461  button->touch_padding = nk_vec2(0.0f,0.0f);
14462  button->userdata = nk_handle_ptr(0);
14463  button->text_alignment = NK_TEXT_CENTERED;
14464  button->border = 1.0f;
14465  button->rounding = 0.0f;
14466  button->draw_begin = 0;
14467  button->draw_end = 0;
14468  style->slider.dec_button = style->slider.inc_button;
14469 
14470  /* progressbar */
14471  prog = &style->progress;
14472  nk_zero_struct(*prog);
14473  prog->normal = nk_style_item_color(table[NK_COLOR_SLIDER]);
14474  prog->hover = nk_style_item_color(table[NK_COLOR_SLIDER]);
14475  prog->active = nk_style_item_color(table[NK_COLOR_SLIDER]);
14479  prog->border_color = nk_rgba(0,0,0,0);
14480  prog->cursor_border_color = nk_rgba(0,0,0,0);
14481  prog->userdata = nk_handle_ptr(0);
14482  prog->padding = nk_vec2(4,4);
14483  prog->rounding = 0;
14484  prog->border = 0;
14485  prog->cursor_rounding = 0;
14486  prog->cursor_border = 0;
14487  prog->draw_begin = 0;
14488  prog->draw_end = 0;
14489 
14490  /* scrollbars */
14491  scroll = &style->scrollh;
14492  nk_zero_struct(*scroll);
14493  scroll->normal = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
14494  scroll->hover = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
14495  scroll->active = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
14501  scroll->userdata = nk_handle_ptr(0);
14502  scroll->border_color = table[NK_COLOR_SCROLLBAR];
14503  scroll->cursor_border_color = table[NK_COLOR_SCROLLBAR];
14504  scroll->padding = nk_vec2(0,0);
14505  scroll->show_buttons = nk_false;
14506  scroll->border = 0;
14507  scroll->rounding = 0;
14508  scroll->border_cursor = 0;
14509  scroll->rounding_cursor = 0;
14510  scroll->draw_begin = 0;
14511  scroll->draw_end = 0;
14512  style->scrollv = style->scrollh;
14513 
14514  /* scrollbars buttons */
14515  button = &style->scrollh.inc_button;
14516  button->normal = nk_style_item_color(nk_rgb(40,40,40));
14517  button->hover = nk_style_item_color(nk_rgb(42,42,42));
14518  button->active = nk_style_item_color(nk_rgb(44,44,44));
14519  button->border_color = nk_rgb(65,65,65);
14520  button->text_background = nk_rgb(40,40,40);
14521  button->text_normal = nk_rgb(175,175,175);
14522  button->text_hover = nk_rgb(175,175,175);
14523  button->text_active = nk_rgb(175,175,175);
14524  button->padding = nk_vec2(4.0f,4.0f);
14525  button->touch_padding = nk_vec2(0.0f,0.0f);
14526  button->userdata = nk_handle_ptr(0);
14527  button->text_alignment = NK_TEXT_CENTERED;
14528  button->border = 1.0f;
14529  button->rounding = 0.0f;
14530  button->draw_begin = 0;
14531  button->draw_end = 0;
14532  style->scrollh.dec_button = style->scrollh.inc_button;
14533  style->scrollv.inc_button = style->scrollh.inc_button;
14534  style->scrollv.dec_button = style->scrollh.inc_button;
14535 
14536  /* edit */
14537  edit = &style->edit;
14538  nk_zero_struct(*edit);
14539  edit->normal = nk_style_item_color(table[NK_COLOR_EDIT]);
14540  edit->hover = nk_style_item_color(table[NK_COLOR_EDIT]);
14541  edit->active = nk_style_item_color(table[NK_COLOR_EDIT]);
14542  edit->cursor_normal = table[NK_COLOR_TEXT];
14543  edit->cursor_hover = table[NK_COLOR_TEXT];
14544  edit->cursor_text_normal= table[NK_COLOR_EDIT];
14545  edit->cursor_text_hover = table[NK_COLOR_EDIT];
14546  edit->border_color = table[NK_COLOR_BORDER];
14547  edit->text_normal = table[NK_COLOR_TEXT];
14548  edit->text_hover = table[NK_COLOR_TEXT];
14549  edit->text_active = table[NK_COLOR_TEXT];
14550  edit->selected_normal = table[NK_COLOR_TEXT];
14551  edit->selected_hover = table[NK_COLOR_TEXT];
14552  edit->selected_text_normal = table[NK_COLOR_EDIT];
14553  edit->selected_text_hover = table[NK_COLOR_EDIT];
14554  edit->scrollbar_size = nk_vec2(10,10);
14555  edit->scrollbar = style->scrollv;
14556  edit->padding = nk_vec2(4,4);
14557  edit->row_padding = 2;
14558  edit->cursor_size = 4;
14559  edit->border = 1;
14560  edit->rounding = 0;
14561 
14562  /* property */
14563  property = &style->property;
14564  nk_zero_struct(*property);
14565  property->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14566  property->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14567  property->active = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14568  property->border_color = table[NK_COLOR_BORDER];
14569  property->label_normal = table[NK_COLOR_TEXT];
14570  property->label_hover = table[NK_COLOR_TEXT];
14571  property->label_active = table[NK_COLOR_TEXT];
14572  property->sym_left = NK_SYMBOL_TRIANGLE_LEFT;
14573  property->sym_right = NK_SYMBOL_TRIANGLE_RIGHT;
14574  property->userdata = nk_handle_ptr(0);
14575  property->padding = nk_vec2(4,4);
14576  property->border = 1;
14577  property->rounding = 10;
14578  property->draw_begin = 0;
14579  property->draw_end = 0;
14580 
14581  /* property buttons */
14582  button = &style->property.dec_button;
14583  nk_zero_struct(*button);
14584  button->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14585  button->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14586  button->active = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14587  button->border_color = nk_rgba(0,0,0,0);
14588  button->text_background = table[NK_COLOR_PROPERTY];
14589  button->text_normal = table[NK_COLOR_TEXT];
14590  button->text_hover = table[NK_COLOR_TEXT];
14591  button->text_active = table[NK_COLOR_TEXT];
14592  button->padding = nk_vec2(0.0f,0.0f);
14593  button->touch_padding = nk_vec2(0.0f,0.0f);
14594  button->userdata = nk_handle_ptr(0);
14595  button->text_alignment = NK_TEXT_CENTERED;
14596  button->border = 0.0f;
14597  button->rounding = 0.0f;
14598  button->draw_begin = 0;
14599  button->draw_end = 0;
14600  style->property.inc_button = style->property.dec_button;
14601 
14602  /* property edit */
14603  edit = &style->property.edit;
14604  nk_zero_struct(*edit);
14608  edit->border_color = nk_rgba(0,0,0,0);
14609  edit->cursor_normal = table[NK_COLOR_TEXT];
14610  edit->cursor_hover = table[NK_COLOR_TEXT];
14611  edit->cursor_text_normal= table[NK_COLOR_EDIT];
14612  edit->cursor_text_hover = table[NK_COLOR_EDIT];
14613  edit->text_normal = table[NK_COLOR_TEXT];
14614  edit->text_hover = table[NK_COLOR_TEXT];
14615  edit->text_active = table[NK_COLOR_TEXT];
14616  edit->selected_normal = table[NK_COLOR_TEXT];
14617  edit->selected_hover = table[NK_COLOR_TEXT];
14618  edit->selected_text_normal = table[NK_COLOR_EDIT];
14619  edit->selected_text_hover = table[NK_COLOR_EDIT];
14620  edit->padding = nk_vec2(0,0);
14621  edit->cursor_size = 8;
14622  edit->border = 0;
14623  edit->rounding = 0;
14624 
14625  /* chart */
14626  chart = &style->chart;
14627  nk_zero_struct(*chart);
14629  chart->border_color = table[NK_COLOR_BORDER];
14631  chart->color = table[NK_COLOR_CHART_COLOR];
14632  chart->padding = nk_vec2(4,4);
14633  chart->border = 0;
14634  chart->rounding = 0;
14635 
14636  /* combo */
14637  combo = &style->combo;
14638  combo->normal = nk_style_item_color(table[NK_COLOR_COMBO]);
14639  combo->hover = nk_style_item_color(table[NK_COLOR_COMBO]);
14640  combo->active = nk_style_item_color(table[NK_COLOR_COMBO]);
14641  combo->border_color = table[NK_COLOR_BORDER];
14642  combo->label_normal = table[NK_COLOR_TEXT];
14643  combo->label_hover = table[NK_COLOR_TEXT];
14644  combo->label_active = table[NK_COLOR_TEXT];
14648  combo->content_padding = nk_vec2(4,4);
14649  combo->button_padding = nk_vec2(0,4);
14650  combo->spacing = nk_vec2(4,0);
14651  combo->border = 1;
14652  combo->rounding = 0;
14653 
14654  /* combo button */
14655  button = &style->combo.button;
14656  nk_zero_struct(*button);
14657  button->normal = nk_style_item_color(table[NK_COLOR_COMBO]);
14658  button->hover = nk_style_item_color(table[NK_COLOR_COMBO]);
14659  button->active = nk_style_item_color(table[NK_COLOR_COMBO]);
14660  button->border_color = nk_rgba(0,0,0,0);
14661  button->text_background = table[NK_COLOR_COMBO];
14662  button->text_normal = table[NK_COLOR_TEXT];
14663  button->text_hover = table[NK_COLOR_TEXT];
14664  button->text_active = table[NK_COLOR_TEXT];
14665  button->padding = nk_vec2(2.0f,2.0f);
14666  button->touch_padding = nk_vec2(0.0f,0.0f);
14667  button->userdata = nk_handle_ptr(0);
14668  button->text_alignment = NK_TEXT_CENTERED;
14669  button->border = 0.0f;
14670  button->rounding = 0.0f;
14671  button->draw_begin = 0;
14672  button->draw_end = 0;
14673 
14674  /* tab */
14675  tab = &style->tab;
14677  tab->border_color = table[NK_COLOR_BORDER];
14678  tab->text = table[NK_COLOR_TEXT];
14681  tab->padding = nk_vec2(4,4);
14682  tab->spacing = nk_vec2(4,4);
14683  tab->indent = 10.0f;
14684  tab->border = 1;
14685  tab->rounding = 0;
14686 
14687  /* tab button */
14688  button = &style->tab.tab_minimize_button;
14689  nk_zero_struct(*button);
14691  button->hover = nk_style_item_color(table[NK_COLOR_TAB_HEADER]);
14693  button->border_color = nk_rgba(0,0,0,0);
14694  button->text_background = table[NK_COLOR_TAB_HEADER];
14695  button->text_normal = table[NK_COLOR_TEXT];
14696  button->text_hover = table[NK_COLOR_TEXT];
14697  button->text_active = table[NK_COLOR_TEXT];
14698  button->padding = nk_vec2(2.0f,2.0f);
14699  button->touch_padding = nk_vec2(0.0f,0.0f);
14700  button->userdata = nk_handle_ptr(0);
14701  button->text_alignment = NK_TEXT_CENTERED;
14702  button->border = 0.0f;
14703  button->rounding = 0.0f;
14704  button->draw_begin = 0;
14705  button->draw_end = 0;
14706  style->tab.tab_maximize_button =*button;
14707 
14708  /* node button */
14709  button = &style->tab.node_minimize_button;
14710  nk_zero_struct(*button);
14711  button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
14712  button->hover = nk_style_item_color(table[NK_COLOR_WINDOW]);
14713  button->active = nk_style_item_color(table[NK_COLOR_WINDOW]);
14714  button->border_color = nk_rgba(0,0,0,0);
14715  button->text_background = table[NK_COLOR_TAB_HEADER];
14716  button->text_normal = table[NK_COLOR_TEXT];
14717  button->text_hover = table[NK_COLOR_TEXT];
14718  button->text_active = table[NK_COLOR_TEXT];
14719  button->padding = nk_vec2(2.0f,2.0f);
14720  button->touch_padding = nk_vec2(0.0f,0.0f);
14721  button->userdata = nk_handle_ptr(0);
14722  button->text_alignment = NK_TEXT_CENTERED;
14723  button->border = 0.0f;
14724  button->rounding = 0.0f;
14725  button->draw_begin = 0;
14726  button->draw_end = 0;
14727  style->tab.node_maximize_button =*button;
14728 
14729  /* window header */
14730  win = &style->window;
14731  win->header.align = NK_HEADER_RIGHT;
14738  win->header.label_normal = table[NK_COLOR_TEXT];
14739  win->header.label_hover = table[NK_COLOR_TEXT];
14740  win->header.label_active = table[NK_COLOR_TEXT];
14741  win->header.label_padding = nk_vec2(4,4);
14742  win->header.padding = nk_vec2(4,4);
14743  win->header.spacing = nk_vec2(0,0);
14744 
14745  /* window header close button */
14746  button = &style->window.header.close_button;
14747  nk_zero_struct(*button);
14748  button->normal = nk_style_item_color(table[NK_COLOR_HEADER]);
14749  button->hover = nk_style_item_color(table[NK_COLOR_HEADER]);
14750  button->active = nk_style_item_color(table[NK_COLOR_HEADER]);
14751  button->border_color = nk_rgba(0,0,0,0);
14752  button->text_background = table[NK_COLOR_HEADER];
14753  button->text_normal = table[NK_COLOR_TEXT];
14754  button->text_hover = table[NK_COLOR_TEXT];
14755  button->text_active = table[NK_COLOR_TEXT];
14756  button->padding = nk_vec2(0.0f,0.0f);
14757  button->touch_padding = nk_vec2(0.0f,0.0f);
14758  button->userdata = nk_handle_ptr(0);
14759  button->text_alignment = NK_TEXT_CENTERED;
14760  button->border = 0.0f;
14761  button->rounding = 0.0f;
14762  button->draw_begin = 0;
14763  button->draw_end = 0;
14764 
14765  /* window header minimize button */
14766  button = &style->window.header.minimize_button;
14767  nk_zero_struct(*button);
14768  button->normal = nk_style_item_color(table[NK_COLOR_HEADER]);
14769  button->hover = nk_style_item_color(table[NK_COLOR_HEADER]);
14770  button->active = nk_style_item_color(table[NK_COLOR_HEADER]);
14771  button->border_color = nk_rgba(0,0,0,0);
14772  button->text_background = table[NK_COLOR_HEADER];
14773  button->text_normal = table[NK_COLOR_TEXT];
14774  button->text_hover = table[NK_COLOR_TEXT];
14775  button->text_active = table[NK_COLOR_TEXT];
14776  button->padding = nk_vec2(0.0f,0.0f);
14777  button->touch_padding = nk_vec2(0.0f,0.0f);
14778  button->userdata = nk_handle_ptr(0);
14779  button->text_alignment = NK_TEXT_CENTERED;
14780  button->border = 0.0f;
14781  button->rounding = 0.0f;
14782  button->draw_begin = 0;
14783  button->draw_end = 0;
14784 
14785  /* window */
14786  win->background = table[NK_COLOR_WINDOW];
14788  win->border_color = table[NK_COLOR_BORDER];
14789  win->popup_border_color = table[NK_COLOR_BORDER];
14790  win->combo_border_color = table[NK_COLOR_BORDER];
14792  win->menu_border_color = table[NK_COLOR_BORDER];
14793  win->group_border_color = table[NK_COLOR_BORDER];
14794  win->tooltip_border_color = table[NK_COLOR_BORDER];
14795  win->scaler = nk_style_item_color(table[NK_COLOR_TEXT]);
14796 
14797  win->rounding = 0.0f;
14798  win->spacing = nk_vec2(4,4);
14799  win->scrollbar_size = nk_vec2(10,10);
14800  win->min_size = nk_vec2(64,64);
14801 
14802  win->combo_border = 1.0f;
14803  win->contextual_border = 1.0f;
14804  win->menu_border = 1.0f;
14805  win->group_border = 1.0f;
14806  win->tooltip_border = 1.0f;
14807  win->popup_border = 1.0f;
14808  win->border = 2.0f;
14809  win->min_row_height_padding = 8;
14810 
14811  win->padding = nk_vec2(4,4);
14812  win->group_padding = nk_vec2(4,4);
14813  win->popup_padding = nk_vec2(4,4);
14814  win->combo_padding = nk_vec2(4,4);
14815  win->contextual_padding = nk_vec2(4,4);
14816  win->menu_padding = nk_vec2(4,4);
14817  win->tooltip_padding = nk_vec2(4,4);
14818 }
14819 NK_API void
14820 nk_style_set_font(struct nk_context *ctx, const struct nk_user_font *font)
14821 {
14822  struct nk_style *style;
14823  NK_ASSERT(ctx);
14824 
14825  if (!ctx) return;
14826  style = &ctx->style;
14827  style->font = font;
14828  ctx->stacks.fonts.head = 0;
14829  if (ctx->current)
14831 }
14832 NK_API int
14833 nk_style_push_font(struct nk_context *ctx, const struct nk_user_font *font)
14834 {
14835  struct nk_config_stack_user_font *font_stack;
14836  struct nk_config_stack_user_font_element *element;
14837 
14838  NK_ASSERT(ctx);
14839  if (!ctx) return 0;
14840 
14841  font_stack = &ctx->stacks.fonts;
14842  NK_ASSERT(font_stack->head < (int)NK_LEN(font_stack->elements));
14843  if (font_stack->head >= (int)NK_LEN(font_stack->elements))
14844  return 0;
14845 
14846  element = &font_stack->elements[font_stack->head++];
14847  element->address = &ctx->style.font;
14848  element->old_value = ctx->style.font;
14849  ctx->style.font = font;
14850  return 1;
14851 }
14852 NK_API int
14854 {
14855  struct nk_config_stack_user_font *font_stack;
14856  struct nk_config_stack_user_font_element *element;
14857 
14858  NK_ASSERT(ctx);
14859  if (!ctx) return 0;
14860 
14861  font_stack = &ctx->stacks.fonts;
14862  NK_ASSERT(font_stack->head > 0);
14863  if (font_stack->head < 1)
14864  return 0;
14865 
14866  element = &font_stack->elements[--font_stack->head];
14867  *element->address = element->old_value;
14868  return 1;
14869 }
14870 #define NK_STYLE_PUSH_IMPLEMENATION(prefix, type, stack) \
14871 nk_style_push_##type(struct nk_context *ctx, prefix##_##type *address, prefix##_##type value)\
14872 {\
14873  struct nk_config_stack_##type * type_stack;\
14874  struct nk_config_stack_##type##_element *element;\
14875  NK_ASSERT(ctx);\
14876  if (!ctx) return 0;\
14877  type_stack = &ctx->stacks.stack;\
14878  NK_ASSERT(type_stack->head < (int)NK_LEN(type_stack->elements));\
14879  if (type_stack->head >= (int)NK_LEN(type_stack->elements))\
14880  return 0;\
14881  element = &type_stack->elements[type_stack->head++];\
14882  element->address = address;\
14883  element->old_value = *address;\
14884  *address = value;\
14885  return 1;\
14886 }
14887 #define NK_STYLE_POP_IMPLEMENATION(type, stack) \
14888 nk_style_pop_##type(struct nk_context *ctx)\
14889 {\
14890  struct nk_config_stack_##type *type_stack;\
14891  struct nk_config_stack_##type##_element *element;\
14892  NK_ASSERT(ctx);\
14893  if (!ctx) return 0;\
14894  type_stack = &ctx->stacks.stack;\
14895  NK_ASSERT(type_stack->head > 0);\
14896  if (type_stack->head < 1)\
14897  return 0;\
14898  element = &type_stack->elements[--type_stack->head];\
14899  *element->address = element->old_value;\
14900  return 1;\
14901 }
14902 NK_API int NK_STYLE_PUSH_IMPLEMENATION(struct nk, style_item, style_items)
14903 NK_API int NK_STYLE_PUSH_IMPLEMENATION(nk,float, floats)
14904 NK_API int NK_STYLE_PUSH_IMPLEMENATION(struct nk, vec2, vectors)
14905 NK_API int NK_STYLE_PUSH_IMPLEMENATION(nk,flags, flags)
14906 NK_API int NK_STYLE_PUSH_IMPLEMENATION(struct nk,color, colors)
14907 
14908 NK_API int NK_STYLE_POP_IMPLEMENATION(style_item, style_items)
14909 NK_API int NK_STYLE_POP_IMPLEMENATION(float,floats)
14910 NK_API int NK_STYLE_POP_IMPLEMENATION(vec2, vectors)
14911 NK_API int NK_STYLE_POP_IMPLEMENATION(flags,flags)
14912 NK_API int NK_STYLE_POP_IMPLEMENATION(color,colors)
14913 
14914 NK_API int
14916 {
14917  struct nk_style *style;
14918  NK_ASSERT(ctx);
14919  if (!ctx) return 0;
14920  style = &ctx->style;
14921  if (style->cursors[c]) {
14922  style->cursor_active = style->cursors[c];
14923  return 1;
14924  }
14925  return 0;
14926 }
14927 NK_API void
14929 {
14931 }
14932 NK_API void
14934 {
14936 }
14937 NK_API void
14938 nk_style_load_cursor(struct nk_context *ctx, enum nk_style_cursor cursor,
14939  const struct nk_cursor *c)
14940 {
14941  struct nk_style *style;
14942  NK_ASSERT(ctx);
14943  if (!ctx) return;
14944  style = &ctx->style;
14945  style->cursors[cursor] = c;
14946 }
14947 NK_API void
14949 {
14950  int i = 0;
14951  struct nk_style *style;
14952  NK_ASSERT(ctx);
14953  if (!ctx) return;
14954  style = &ctx->style;
14955  for (i = 0; i < NK_CURSOR_COUNT; ++i)
14956  style->cursors[i] = &cursors[i];
14957  style->cursor_visible = nk_true;
14958 }
14959 
14960 
14961 
14962 
14963 
14964 /* ==============================================================
14965  *
14966  * CONTEXT
14967  *
14968  * ===============================================================*/
14969 NK_INTERN void
14970 nk_setup(struct nk_context *ctx, const struct nk_user_font *font)
14971 {
14972  NK_ASSERT(ctx);
14973  if (!ctx) return;
14974  nk_zero_struct(*ctx);
14976  ctx->seq = 1;
14977  if (font) ctx->style.font = font;
14978 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
14979  nk_draw_list_init(&ctx->draw_list);
14980 #endif
14981 }
14982 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
14983 NK_API int
14984 nk_init_default(struct nk_context *ctx, const struct nk_user_font *font)
14985 {
14986  struct nk_allocator alloc;
14987  alloc.userdata.ptr = 0;
14988  alloc.alloc = nk_malloc;
14989  alloc.free = nk_mfree;
14990  return nk_init(ctx, &alloc, font);
14991 }
14992 #endif
14993 NK_API int
14994 nk_init_fixed(struct nk_context *ctx, void *memory, nk_size size,
14995  const struct nk_user_font *font)
14996 {
14997  NK_ASSERT(memory);
14998  if (!memory) return 0;
14999  nk_setup(ctx, font);
15000  nk_buffer_init_fixed(&ctx->memory, memory, size);
15001  ctx->use_pool = nk_false;
15002  return 1;
15003 }
15004 NK_API int
15005 nk_init_custom(struct nk_context *ctx, struct nk_buffer *cmds,
15006  struct nk_buffer *pool, const struct nk_user_font *font)
15007 {
15008  NK_ASSERT(cmds);
15009  NK_ASSERT(pool);
15010  if (!cmds || !pool) return 0;
15011 
15012  nk_setup(ctx, font);
15013  ctx->memory = *cmds;
15014  if (pool->type == NK_BUFFER_FIXED) {
15015  /* take memory from buffer and alloc fixed pool */
15016  nk_pool_init_fixed(&ctx->pool, pool->memory.ptr, pool->memory.size);
15017  } else {
15018  /* create dynamic pool from buffer allocator */
15019  struct nk_allocator *alloc = &pool->pool;
15020  nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY);
15021  }
15022  ctx->use_pool = nk_true;
15023  return 1;
15024 }
15025 NK_API int
15026 nk_init(struct nk_context *ctx, struct nk_allocator *alloc,
15027  const struct nk_user_font *font)
15028 {
15029  NK_ASSERT(alloc);
15030  if (!alloc) return 0;
15031  nk_setup(ctx, font);
15032  nk_buffer_init(&ctx->memory, alloc, NK_DEFAULT_COMMAND_BUFFER_SIZE);
15033  nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY);
15034  ctx->use_pool = nk_true;
15035  return 1;
15036 }
15037 #ifdef NK_INCLUDE_COMMAND_USERDATA
15038 NK_API void
15039 nk_set_user_data(struct nk_context *ctx, nk_handle handle)
15040 {
15041  if (!ctx) return;
15042  ctx->userdata = handle;
15043  if (ctx->current)
15044  ctx->current->buffer.userdata = handle;
15045 }
15046 #endif
15047 NK_API void
15048 nk_free(struct nk_context *ctx)
15049 {
15050  NK_ASSERT(ctx);
15051  if (!ctx) return;
15053  if (ctx->use_pool)
15054  nk_pool_free(&ctx->pool);
15055 
15056  nk_zero(&ctx->input, sizeof(ctx->input));
15057  nk_zero(&ctx->style, sizeof(ctx->style));
15058  nk_zero(&ctx->memory, sizeof(ctx->memory));
15059 
15060  ctx->seq = 0;
15061  ctx->build = 0;
15062  ctx->begin = 0;
15063  ctx->end = 0;
15064  ctx->active = 0;
15065  ctx->current = 0;
15066  ctx->freelist = 0;
15067  ctx->count = 0;
15068 }
15069 NK_API void
15070 nk_clear(struct nk_context *ctx)
15071 {
15072  struct nk_window *iter;
15073  struct nk_window *next;
15074  NK_ASSERT(ctx);
15075 
15076  if (!ctx) return;
15077  if (ctx->use_pool)
15080 
15081  ctx->build = 0;
15082  ctx->memory.calls = 0;
15083  ctx->last_widget_state = 0;
15085  NK_MEMSET(&ctx->overlay, 0, sizeof(ctx->overlay));
15086 
15087  /* garbage collector */
15088  iter = ctx->begin;
15089  while (iter) {
15090  /* make sure valid minimized windows do not get removed */
15091  if ((iter->flags & NK_WINDOW_MINIMIZED) &&
15092  !(iter->flags & NK_WINDOW_CLOSED) &&
15093  iter->seq == ctx->seq) {
15094  iter = iter->next;
15095  continue;
15096  }
15097  /* remove hotness from hidden or closed windows*/
15098  if (((iter->flags & NK_WINDOW_HIDDEN) ||
15099  (iter->flags & NK_WINDOW_CLOSED)) &&
15100  iter == ctx->active) {
15101  ctx->active = iter->prev;
15102  ctx->end = iter->prev;
15103  if (!ctx->end)
15104  ctx->begin = 0;
15105  if (ctx->active)
15106  ctx->active->flags &= ~(unsigned)NK_WINDOW_ROM;
15107  }
15108  /* free unused popup windows */
15109  if (iter->popup.win && iter->popup.win->seq != ctx->seq) {
15110  nk_free_window(ctx, iter->popup.win);
15111  iter->popup.win = 0;
15112  }
15113  /* remove unused window state tables */
15114  {struct nk_table *n, *it = iter->tables;
15115  while (it) {
15116  n = it->next;
15117  if (it->seq != ctx->seq) {
15118  nk_remove_table(iter, it);
15119  nk_zero(it, sizeof(union nk_page_data));
15120  nk_free_table(ctx, it);
15121  if (it == iter->tables)
15122  iter->tables = n;
15123  } it = n;
15124  }}
15125  /* window itself is not used anymore so free */
15126  if (iter->seq != ctx->seq || iter->flags & NK_WINDOW_CLOSED) {
15127  next = iter->next;
15128  nk_remove_window(ctx, iter);
15129  nk_free_window(ctx, iter);
15130  iter = next;
15131  } else iter = iter->next;
15132  }
15133  ctx->seq++;
15134 }
15135 NK_LIB void
15136 nk_start_buffer(struct nk_context *ctx, struct nk_command_buffer *buffer)
15137 {
15138  NK_ASSERT(ctx);
15139  NK_ASSERT(buffer);
15140  if (!ctx || !buffer) return;
15141  buffer->begin = ctx->memory.allocated;
15142  buffer->end = buffer->begin;
15143  buffer->last = buffer->begin;
15144  buffer->clip = nk_null_rect;
15145 }
15146 NK_LIB void
15147 nk_start(struct nk_context *ctx, struct nk_window *win)
15148 {
15149  NK_ASSERT(ctx);
15150  NK_ASSERT(win);
15151  nk_start_buffer(ctx, &win->buffer);
15152 }
15153 NK_LIB void
15154 nk_start_popup(struct nk_context *ctx, struct nk_window *win)
15155 {
15156  struct nk_popup_buffer *buf;
15157  NK_ASSERT(ctx);
15158  NK_ASSERT(win);
15159  if (!ctx || !win) return;
15160 
15161  /* save buffer fill state for popup */
15162  buf = &win->popup.buf;
15163  buf->begin = win->buffer.end;
15164  buf->end = win->buffer.end;
15165  buf->parent = win->buffer.last;
15166  buf->last = buf->begin;
15167  buf->active = nk_true;
15168 }
15169 NK_LIB void
15170 nk_finish_popup(struct nk_context *ctx, struct nk_window *win)
15171 {
15172  struct nk_popup_buffer *buf;
15173  NK_ASSERT(ctx);
15174  NK_ASSERT(win);
15175  if (!ctx || !win) return;
15176 
15177  buf = &win->popup.buf;
15178  buf->last = win->buffer.last;
15179  buf->end = win->buffer.end;
15180 }
15181 NK_LIB void
15182 nk_finish_buffer(struct nk_context *ctx, struct nk_command_buffer *buffer)
15183 {
15184  NK_ASSERT(ctx);
15185  NK_ASSERT(buffer);
15186  if (!ctx || !buffer) return;
15187  buffer->end = ctx->memory.allocated;
15188 }
15189 NK_LIB void
15190 nk_finish(struct nk_context *ctx, struct nk_window *win)
15191 {
15192  struct nk_popup_buffer *buf;
15193  struct nk_command *parent_last;
15194  void *memory;
15195 
15196  NK_ASSERT(ctx);
15197  NK_ASSERT(win);
15198  if (!ctx || !win) return;
15199  nk_finish_buffer(ctx, &win->buffer);
15200  if (!win->popup.buf.active) return;
15201 
15202  buf = &win->popup.buf;
15203  memory = ctx->memory.memory.ptr;
15204  parent_last = nk_ptr_add(struct nk_command, memory, buf->parent);
15205  parent_last->next = buf->end;
15206 }
15207 NK_LIB void
15208 nk_build(struct nk_context *ctx)
15209 {
15210  struct nk_window *it = 0;
15211  struct nk_command *cmd = 0;
15212  nk_byte *buffer = 0;
15213 
15214  /* draw cursor overlay */
15215  if (!ctx->style.cursor_active)
15218  struct nk_rect mouse_bounds;
15219  const struct nk_cursor *cursor = ctx->style.cursor_active;
15220  nk_command_buffer_init(&ctx->overlay, &ctx->memory, NK_CLIPPING_OFF);
15221  nk_start_buffer(ctx, &ctx->overlay);
15222 
15223  mouse_bounds.x = ctx->input.mouse.pos.x - cursor->offset.x;
15224  mouse_bounds.y = ctx->input.mouse.pos.y - cursor->offset.y;
15225  mouse_bounds.w = cursor->size.x;
15226  mouse_bounds.h = cursor->size.y;
15227 
15228  nk_draw_image(&ctx->overlay, mouse_bounds, &cursor->img, nk_white);
15229  nk_finish_buffer(ctx, &ctx->overlay);
15230  }
15231  /* build one big draw command list out of all window buffers */
15232  it = ctx->begin;
15233  buffer = (nk_byte*)ctx->memory.memory.ptr;
15234  while (it != 0) {
15235  struct nk_window *next = it->next;
15236  if (it->buffer.last == it->buffer.begin || (it->flags & NK_WINDOW_HIDDEN)||
15237  it->seq != ctx->seq)
15238  goto cont;
15239 
15240  cmd = nk_ptr_add(struct nk_command, buffer, it->buffer.last);
15241  while (next && ((next->buffer.last == next->buffer.begin) ||
15242  (next->flags & NK_WINDOW_HIDDEN) || next->seq != ctx->seq))
15243  next = next->next; /* skip empty command buffers */
15244 
15245  if (next) cmd->next = next->buffer.begin;
15246  cont: it = next;
15247  }
15248  /* append all popup draw commands into lists */
15249  it = ctx->begin;
15250  while (it != 0) {
15251  struct nk_window *next = it->next;
15252  struct nk_popup_buffer *buf;
15253  if (!it->popup.buf.active)
15254  goto skip;
15255 
15256  buf = &it->popup.buf;
15257  cmd->next = buf->begin;
15258  cmd = nk_ptr_add(struct nk_command, buffer, buf->last);
15259  buf->active = nk_false;
15260  skip: it = next;
15261  }
15262  if (cmd) {
15263  /* append overlay commands */
15264  if (ctx->overlay.end != ctx->overlay.begin)
15265  cmd->next = ctx->overlay.begin;
15266  else cmd->next = ctx->memory.allocated;
15267  }
15268 }
15269 NK_API const struct nk_command*
15270 nk__begin(struct nk_context *ctx)
15271 {
15272  struct nk_window *iter;
15273  nk_byte *buffer;
15274  NK_ASSERT(ctx);
15275  if (!ctx) return 0;
15276  if (!ctx->count) return 0;
15277 
15279  if (!ctx->build) {
15280  nk_build(ctx);
15281  ctx->build = nk_true;
15282  }
15283  iter = ctx->begin;
15284  while (iter && ((iter->buffer.begin == iter->buffer.end) ||
15285  (iter->flags & NK_WINDOW_HIDDEN) || iter->seq != ctx->seq))
15286  iter = iter->next;
15287  if (!iter) return 0;
15288  return nk_ptr_add_const(struct nk_command, buffer, iter->buffer.begin);
15289 }
15290 
15291 NK_API const struct nk_command*
15292 nk__next(struct nk_context *ctx, const struct nk_command *cmd)
15293 {
15294  nk_byte *buffer;
15295  const struct nk_command *next;
15296  NK_ASSERT(ctx);
15297  if (!ctx || !cmd || !ctx->count) return 0;
15298  if (cmd->next >= ctx->memory.allocated) return 0;
15299  buffer = (nk_byte*)ctx->memory.memory.ptr;
15300  next = nk_ptr_add_const(struct nk_command, buffer, cmd->next);
15301  return next;
15302 }
15303 
15304 
15305 
15306 
15307 
15308 
15309 /* ===============================================================
15310  *
15311  * POOL
15312  *
15313  * ===============================================================*/
15314 NK_LIB void
15315 nk_pool_init(struct nk_pool *pool, struct nk_allocator *alloc,
15316  unsigned int capacity)
15317 {
15318  nk_zero(pool, sizeof(*pool));
15319  pool->alloc = *alloc;
15320  pool->capacity = capacity;
15321  pool->type = NK_BUFFER_DYNAMIC;
15322  pool->pages = 0;
15323 }
15324 NK_LIB void
15325 nk_pool_free(struct nk_pool *pool)
15326 {
15327  struct nk_page *iter = pool->pages;
15328  if (!pool) return;
15329  if (pool->type == NK_BUFFER_FIXED) return;
15330  while (iter) {
15331  struct nk_page *next = iter->next;
15332  pool->alloc.free(pool->alloc.userdata, iter);
15333  iter = next;
15334  }
15335 }
15336 NK_LIB void
15337 nk_pool_init_fixed(struct nk_pool *pool, void *memory, nk_size size)
15338 {
15339  nk_zero(pool, sizeof(*pool));
15340  NK_ASSERT(size >= sizeof(struct nk_page));
15341  if (size < sizeof(struct nk_page)) return;
15342  pool->capacity = (unsigned)(size - sizeof(struct nk_page)) / sizeof(struct nk_page_element);
15343  pool->pages = (struct nk_page*)memory;
15344  pool->type = NK_BUFFER_FIXED;
15345  pool->size = size;
15346 }
15347 NK_LIB struct nk_page_element*
15348 nk_pool_alloc(struct nk_pool *pool)
15349 {
15350  if (!pool->pages || pool->pages->size >= pool->capacity) {
15351  /* allocate new page */
15352  struct nk_page *page;
15353  if (pool->type == NK_BUFFER_FIXED) {
15354  NK_ASSERT(pool->pages);
15355  if (!pool->pages) return 0;
15356  NK_ASSERT(pool->pages->size < pool->capacity);
15357  return 0;
15358  } else {
15359  nk_size size = sizeof(struct nk_page);
15360  size += NK_POOL_DEFAULT_CAPACITY * sizeof(union nk_page_data);
15361  page = (struct nk_page*)pool->alloc.alloc(pool->alloc.userdata,0, size);
15362  page->next = pool->pages;
15363  pool->pages = page;
15364  page->size = 0;
15365  }
15366  } return &pool->pages->win[pool->pages->size++];
15367 }
15368 
15369 
15370 
15371 
15372 
15373 /* ===============================================================
15374  *
15375  * PAGE ELEMENT
15376  *
15377  * ===============================================================*/
15378 NK_LIB struct nk_page_element*
15379 nk_create_page_element(struct nk_context *ctx)
15380 {
15381  struct nk_page_element *elem;
15382  if (ctx->freelist) {
15383  /* unlink page element from free list */
15384  elem = ctx->freelist;
15385  ctx->freelist = elem->next;
15386  } else if (ctx->use_pool) {
15387  /* allocate page element from memory pool */
15388  elem = nk_pool_alloc(&ctx->pool);
15389  NK_ASSERT(elem);
15390  if (!elem) return 0;
15391  } else {
15392  /* allocate new page element from back of fixed size memory buffer */
15393  NK_STORAGE const nk_size size = sizeof(struct nk_page_element);
15394  NK_STORAGE const nk_size align = NK_ALIGNOF(struct nk_page_element);
15395  elem = (struct nk_page_element*)nk_buffer_alloc(&ctx->memory, NK_BUFFER_BACK, size, align);
15396  NK_ASSERT(elem);
15397  if (!elem) return 0;
15398  }
15399  nk_zero_struct(*elem);
15400  elem->next = 0;
15401  elem->prev = 0;
15402  return elem;
15403 }
15404 NK_LIB void
15405 nk_link_page_element_into_freelist(struct nk_context *ctx,
15406  struct nk_page_element *elem)
15407 {
15408  /* link table into freelist */
15409  if (!ctx->freelist) {
15410  ctx->freelist = elem;
15411  } else {
15412  elem->next = ctx->freelist;
15413  ctx->freelist = elem;
15414  }
15415 }
15416 NK_LIB void
15417 nk_free_page_element(struct nk_context *ctx, struct nk_page_element *elem)
15418 {
15419  /* we have a pool so just add to free list */
15420  if (ctx->use_pool) {
15421  nk_link_page_element_into_freelist(ctx, elem);
15422  return;
15423  }
15424  /* if possible remove last element from back of fixed memory buffer */
15425  {void *elem_end = (void*)(elem + 1);
15426  void *buffer_end = (nk_byte*)ctx->memory.memory.ptr + ctx->memory.size;
15427  if (elem_end == buffer_end)
15428  ctx->memory.size -= sizeof(struct nk_page_element);
15429  else nk_link_page_element_into_freelist(ctx, elem);}
15430 }
15431 
15432 
15433 
15434 
15435 
15436 /* ===============================================================
15437  *
15438  * TABLE
15439  *
15440  * ===============================================================*/
15441 NK_LIB struct nk_table*
15442 nk_create_table(struct nk_context *ctx)
15443 {
15444  struct nk_page_element *elem;
15445  elem = nk_create_page_element(ctx);
15446  if (!elem) return 0;
15447  nk_zero_struct(*elem);
15448  return &elem->data.tbl;
15449 }
15450 NK_LIB void
15451 nk_free_table(struct nk_context *ctx, struct nk_table *tbl)
15452 {
15453  union nk_page_data *pd = NK_CONTAINER_OF(tbl, union nk_page_data, tbl);
15454  struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data);
15455  nk_free_page_element(ctx, pe);
15456 }
15457 NK_LIB void
15458 nk_push_table(struct nk_window *win, struct nk_table *tbl)
15459 {
15460  if (!win->tables) {
15461  win->tables = tbl;
15462  tbl->next = 0;
15463  tbl->prev = 0;
15464  tbl->size = 0;
15465  win->table_count = 1;
15466  return;
15467  }
15468  win->tables->prev = tbl;
15469  tbl->next = win->tables;
15470  tbl->prev = 0;
15471  tbl->size = 0;
15472  win->tables = tbl;
15473  win->table_count++;
15474 }
15475 NK_LIB void
15476 nk_remove_table(struct nk_window *win, struct nk_table *tbl)
15477 {
15478  if (win->tables == tbl)
15479  win->tables = tbl->next;
15480  if (tbl->next)
15481  tbl->next->prev = tbl->prev;
15482  if (tbl->prev)
15483  tbl->prev->next = tbl->next;
15484  tbl->next = 0;
15485  tbl->prev = 0;
15486 }
15487 NK_LIB nk_uint*
15488 nk_add_value(struct nk_context *ctx, struct nk_window *win,
15489  nk_hash name, nk_uint value)
15490 {
15491  NK_ASSERT(ctx);
15492  NK_ASSERT(win);
15493  if (!win || !ctx) return 0;
15494  if (!win->tables || win->tables->size >= NK_VALUE_PAGE_CAPACITY) {
15495  struct nk_table *tbl = nk_create_table(ctx);
15496  NK_ASSERT(tbl);
15497  if (!tbl) return 0;
15498  nk_push_table(win, tbl);
15499  }
15500  win->tables->seq = win->seq;
15501  win->tables->keys[win->tables->size] = name;
15502  win->tables->values[win->tables->size] = value;
15503  return &win->tables->values[win->tables->size++];
15504 }
15505 NK_LIB nk_uint*
15506 nk_find_value(struct nk_window *win, nk_hash name)
15507 {
15508  struct nk_table *iter = win->tables;
15509  while (iter) {
15510  unsigned int i = 0;
15511  unsigned int size = iter->size;
15512  for (i = 0; i < size; ++i) {
15513  if (iter->keys[i] == name) {
15514  iter->seq = win->seq;
15515  return &iter->values[i];
15516  }
15518  iter = iter->next;
15519  }
15520  return 0;
15521 }
15522 
15523 
15524 
15525 
15526 
15527 /* ===============================================================
15528  *
15529  * PANEL
15530  *
15531  * ===============================================================*/
15532 NK_LIB void*
15533 nk_create_panel(struct nk_context *ctx)
15534 {
15535  struct nk_page_element *elem;
15536  elem = nk_create_page_element(ctx);
15537  if (!elem) return 0;
15538  nk_zero_struct(*elem);
15539  return &elem->data.pan;
15540 }
15541 NK_LIB void
15542 nk_free_panel(struct nk_context *ctx, struct nk_panel *pan)
15543 {
15544  union nk_page_data *pd = NK_CONTAINER_OF(pan, union nk_page_data, pan);
15545  struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data);
15546  nk_free_page_element(ctx, pe);
15547 }
15548 NK_LIB int
15549 nk_panel_has_header(nk_flags flags, const char *title)
15550 {
15551  int active = 0;
15552  active = (flags & (NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE));
15553  active = active || (flags & NK_WINDOW_TITLE);
15554  active = active && !(flags & NK_WINDOW_HIDDEN) && title;
15555  return active;
15556 }
15557 NK_LIB struct nk_vec2
15558 nk_panel_get_padding(const struct nk_style *style, enum nk_panel_type type)
15559 {
15560  switch (type) {
15561  default:
15562  case NK_PANEL_WINDOW: return style->window.padding;
15563  case NK_PANEL_GROUP: return style->window.group_padding;
15564  case NK_PANEL_POPUP: return style->window.popup_padding;
15565  case NK_PANEL_CONTEXTUAL: return style->window.contextual_padding;
15566  case NK_PANEL_COMBO: return style->window.combo_padding;
15567  case NK_PANEL_MENU: return style->window.menu_padding;
15568  case NK_PANEL_TOOLTIP: return style->window.menu_padding;}
15569 }
15570 NK_LIB float
15571 nk_panel_get_border(const struct nk_style *style, nk_flags flags,
15572  enum nk_panel_type type)
15573 {
15574  if (flags & NK_WINDOW_BORDER) {
15575  switch (type) {
15576  default:
15577  case NK_PANEL_WINDOW: return style->window.border;
15578  case NK_PANEL_GROUP: return style->window.group_border;
15579  case NK_PANEL_POPUP: return style->window.popup_border;
15580  case NK_PANEL_CONTEXTUAL: return style->window.contextual_border;
15581  case NK_PANEL_COMBO: return style->window.combo_border;
15582  case NK_PANEL_MENU: return style->window.menu_border;
15583  case NK_PANEL_TOOLTIP: return style->window.menu_border;
15584  }} else return 0;
15585 }
15586 NK_LIB struct nk_color
15587 nk_panel_get_border_color(const struct nk_style *style, enum nk_panel_type type)
15588 {
15589  switch (type) {
15590  default:
15591  case NK_PANEL_WINDOW: return style->window.border_color;
15592  case NK_PANEL_GROUP: return style->window.group_border_color;
15593  case NK_PANEL_POPUP: return style->window.popup_border_color;
15594  case NK_PANEL_CONTEXTUAL: return style->window.contextual_border_color;
15595  case NK_PANEL_COMBO: return style->window.combo_border_color;
15596  case NK_PANEL_MENU: return style->window.menu_border_color;
15597  case NK_PANEL_TOOLTIP: return style->window.menu_border_color;}
15598 }
15599 NK_LIB int
15600 nk_panel_is_sub(enum nk_panel_type type)
15601 {
15602  return (type & NK_PANEL_SET_SUB)?1:0;
15603 }
15604 NK_LIB int
15605 nk_panel_is_nonblock(enum nk_panel_type type)
15606 {
15607  return (type & NK_PANEL_SET_NONBLOCK)?1:0;
15608 }
15609 NK_LIB int
15610 nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type panel_type)
15611 {
15612  struct nk_input *in;
15613  struct nk_window *win;
15614  struct nk_panel *layout;
15615  struct nk_command_buffer *out;
15616  const struct nk_style *style;
15617  const struct nk_user_font *font;
15618 
15619  struct nk_vec2 scrollbar_size;
15620  struct nk_vec2 panel_padding;
15621 
15622  NK_ASSERT(ctx);
15623  NK_ASSERT(ctx->current);
15624  NK_ASSERT(ctx->current->layout);
15625  if (!ctx || !ctx->current || !ctx->current->layout) return 0;
15626  nk_zero(ctx->current->layout, sizeof(*ctx->current->layout));
15628  nk_zero(ctx->current->layout, sizeof(struct nk_panel));
15629  ctx->current->layout->type = panel_type;
15630  return 0;
15631  }
15632  /* pull state into local stack */
15633  style = &ctx->style;
15634  font = style->font;
15635  win = ctx->current;
15636  layout = win->layout;
15637  out = &win->buffer;
15638  in = (win->flags & NK_WINDOW_NO_INPUT) ? 0: &ctx->input;
15639 #ifdef NK_INCLUDE_COMMAND_USERDATA
15640  win->buffer.userdata = ctx->userdata;
15641 #endif
15642  /* pull style configuration into local stack */
15643  scrollbar_size = style->window.scrollbar_size;
15644  panel_padding = nk_panel_get_padding(style, panel_type);
15645 
15646  /* window movement */
15647  if ((win->flags & NK_WINDOW_MOVABLE) && !(win->flags & NK_WINDOW_ROM)) {
15648  int left_mouse_down;
15649  int left_mouse_clicked;
15650  int left_mouse_click_in_cursor;
15651 
15652  /* calculate draggable window space */
15653  struct nk_rect header;
15654  header.x = win->bounds.x;
15655  header.y = win->bounds.y;
15656  header.w = win->bounds.w;
15657  if (nk_panel_has_header(win->flags, title)) {
15658  header.h = font->height + 2.0f * style->window.header.padding.y;
15659  header.h += 2.0f * style->window.header.label_padding.y;
15660  } else header.h = panel_padding.y;
15661 
15662  /* window movement by dragging */
15663  left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
15664  left_mouse_clicked = (int)in->mouse.buttons[NK_BUTTON_LEFT].clicked;
15665  left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in,
15666  NK_BUTTON_LEFT, header, nk_true);
15667  if (left_mouse_down && left_mouse_click_in_cursor && !left_mouse_clicked) {
15668  win->bounds.x = win->bounds.x + in->mouse.delta.x;
15669  win->bounds.y = win->bounds.y + in->mouse.delta.y;
15673  }
15674  }
15675 
15676  /* setup panel */
15677  layout->type = panel_type;
15678  layout->flags = win->flags;
15679  layout->bounds = win->bounds;
15680  layout->bounds.x += panel_padding.x;
15681  layout->bounds.w -= 2*panel_padding.x;
15682  if (win->flags & NK_WINDOW_BORDER) {
15683  layout->border = nk_panel_get_border(style, win->flags, panel_type);
15684  layout->bounds = nk_shrink_rect(layout->bounds, layout->border);
15685  } else layout->border = 0;
15686  layout->at_y = layout->bounds.y;
15687  layout->at_x = layout->bounds.x;
15688  layout->max_x = 0;
15689  layout->header_height = 0;
15690  layout->footer_height = 0;
15692  layout->row.index = 0;
15693  layout->row.columns = 0;
15694  layout->row.ratio = 0;
15695  layout->row.item_width = 0;
15696  layout->row.tree_depth = 0;
15697  layout->row.height = panel_padding.y;
15698  layout->has_scrolling = nk_true;
15699  if (!(win->flags & NK_WINDOW_NO_SCROLLBAR))
15700  layout->bounds.w -= scrollbar_size.x;
15701  if (!nk_panel_is_nonblock(panel_type)) {
15702  layout->footer_height = 0;
15703  if (!(win->flags & NK_WINDOW_NO_SCROLLBAR) || win->flags & NK_WINDOW_SCALABLE)
15704  layout->footer_height = scrollbar_size.y;
15705  layout->bounds.h -= layout->footer_height;
15706  }
15707 
15708  /* panel header */
15709  if (nk_panel_has_header(win->flags, title))
15710  {
15711  struct nk_text text;
15712  struct nk_rect header;
15713  const struct nk_style_item *background = 0;
15714 
15715  /* calculate header bounds */
15716  header.x = win->bounds.x;
15717  header.y = win->bounds.y;
15718  header.w = win->bounds.w;
15719  header.h = font->height + 2.0f * style->window.header.padding.y;
15720  header.h += (2.0f * style->window.header.label_padding.y);
15721 
15722  /* shrink panel by header */
15723  layout->header_height = header.h;
15724  layout->bounds.y += header.h;
15725  layout->bounds.h -= header.h;
15726  layout->at_y += header.h;
15727 
15728  /* select correct header background and text color */
15729  if (ctx->active == win) {
15730  background = &style->window.header.active;
15731  text.text = style->window.header.label_active;
15732  } else if (nk_input_is_mouse_hovering_rect(&ctx->input, header)) {
15733  background = &style->window.header.hover;
15734  text.text = style->window.header.label_hover;
15735  } else {
15736  background = &style->window.header.normal;
15737  text.text = style->window.header.label_normal;
15738  }
15739 
15740  /* draw header background */
15741  header.h += 1.0f;
15742  if (background->type == NK_STYLE_ITEM_IMAGE) {
15743  text.background = nk_rgba(0,0,0,0);
15744  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
15745  } else {
15746  text.background = background->data.color;
15747  nk_fill_rect(out, header, 0, background->data.color);
15748  }
15749 
15750  /* window close button */
15751  {struct nk_rect button;
15752  button.y = header.y + style->window.header.padding.y;
15753  button.h = header.h - 2 * style->window.header.padding.y;
15754  button.w = button.h;
15755  if (win->flags & NK_WINDOW_CLOSABLE) {
15756  nk_flags ws = 0;
15757  if (style->window.header.align == NK_HEADER_RIGHT) {
15758  button.x = (header.w + header.x) - (button.w + style->window.header.padding.x);
15759  header.w -= button.w + style->window.header.spacing.x + style->window.header.padding.x;
15760  } else {
15761  button.x = header.x + style->window.header.padding.x;
15762  header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x;
15763  }
15764 
15765  if (nk_do_button_symbol(&ws, &win->buffer, button,
15767  &style->window.header.close_button, in, style->font) && !(win->flags & NK_WINDOW_ROM))
15768  {
15769  layout->flags |= NK_WINDOW_HIDDEN;
15770  layout->flags &= (nk_flags)~NK_WINDOW_MINIMIZED;
15771  }
15772  }
15773 
15774  /* window minimize button */
15775  if (win->flags & NK_WINDOW_MINIMIZABLE) {
15776  nk_flags ws = 0;
15777  if (style->window.header.align == NK_HEADER_RIGHT) {
15778  button.x = (header.w + header.x) - button.w;
15779  if (!(win->flags & NK_WINDOW_CLOSABLE)) {
15780  button.x -= style->window.header.padding.x;
15781  header.w -= style->window.header.padding.x;
15782  }
15783  header.w -= button.w + style->window.header.spacing.x;
15784  } else {
15785  button.x = header.x;
15786  header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x;
15787  }
15788  if (nk_do_button_symbol(&ws, &win->buffer, button, (layout->flags & NK_WINDOW_MINIMIZED)?
15790  NK_BUTTON_DEFAULT, &style->window.header.minimize_button, in, style->font) && !(win->flags & NK_WINDOW_ROM))
15791  layout->flags = (layout->flags & NK_WINDOW_MINIMIZED) ?
15792  layout->flags & (nk_flags)~NK_WINDOW_MINIMIZED:
15793  layout->flags | NK_WINDOW_MINIMIZED;
15794  }}
15795 
15796  {/* window header title */
15797  int text_len = nk_strlen(title);
15798  struct nk_rect label = {0,0,0,0};
15799  float t = font->width(font->userdata, font->height, title, text_len);
15800  text.padding = nk_vec2(0,0);
15801 
15802  label.x = header.x + style->window.header.padding.x;
15803  label.x += style->window.header.label_padding.x;
15804  label.y = header.y + style->window.header.label_padding.y;
15805  label.h = font->height + 2 * style->window.header.label_padding.y;
15806  label.w = t + 2 * style->window.header.spacing.x;
15807  label.w = NK_CLAMP(0, label.w, header.x + header.w - label.x);
15808  nk_widget_text(out, label,(const char*)title, text_len, &text, NK_TEXT_LEFT, font);}
15809  }
15810 
15811  /* draw window background */
15812  if (!(layout->flags & NK_WINDOW_MINIMIZED) && !(layout->flags & NK_WINDOW_DYNAMIC)) {
15813  struct nk_rect body;
15814  body.x = win->bounds.x;
15815  body.w = win->bounds.w;
15816  body.y = (win->bounds.y + layout->header_height);
15817  body.h = (win->bounds.h - layout->header_height);
15819  nk_draw_image(out, body, &style->window.fixed_background.data.image, nk_white);
15820  else nk_fill_rect(out, body, 0, style->window.fixed_background.data.color);
15821  }
15822 
15823  /* set clipping rectangle */
15824  {struct nk_rect clip;
15825  layout->clip = layout->bounds;
15826  nk_unify(&clip, &win->buffer.clip, layout->clip.x, layout->clip.y,
15827  layout->clip.x + layout->clip.w, layout->clip.y + layout->clip.h);
15828  nk_push_scissor(out, clip);
15829  layout->clip = clip;}
15830  return !(layout->flags & NK_WINDOW_HIDDEN) && !(layout->flags & NK_WINDOW_MINIMIZED);
15831 }
15832 NK_LIB void
15833 nk_panel_end(struct nk_context *ctx)
15834 {
15835  struct nk_input *in;
15836  struct nk_window *window;
15837  struct nk_panel *layout;
15838  const struct nk_style *style;
15839  struct nk_command_buffer *out;
15840 
15841  struct nk_vec2 scrollbar_size;
15842  struct nk_vec2 panel_padding;
15843 
15844  NK_ASSERT(ctx);
15845  NK_ASSERT(ctx->current);
15846  NK_ASSERT(ctx->current->layout);
15847  if (!ctx || !ctx->current || !ctx->current->layout)
15848  return;
15849 
15850  window = ctx->current;
15851  layout = window->layout;
15852  style = &ctx->style;
15853  out = &window->buffer;
15854  in = (layout->flags & NK_WINDOW_ROM || layout->flags & NK_WINDOW_NO_INPUT) ? 0 :&ctx->input;
15855  if (!nk_panel_is_sub(layout->type))
15856  nk_push_scissor(out, nk_null_rect);
15857 
15858  /* cache configuration data */
15859  scrollbar_size = style->window.scrollbar_size;
15860  panel_padding = nk_panel_get_padding(style, layout->type);
15861 
15862  /* update the current cursor Y-position to point over the last added widget */
15863  layout->at_y += layout->row.height;
15864 
15865  /* dynamic panels */
15866  if (layout->flags & NK_WINDOW_DYNAMIC && !(layout->flags & NK_WINDOW_MINIMIZED))
15867  {
15868  /* update panel height to fit dynamic growth */
15869  struct nk_rect empty_space;
15870  if (layout->at_y < (layout->bounds.y + layout->bounds.h))
15871  layout->bounds.h = layout->at_y - layout->bounds.y;
15872 
15873  /* fill top empty space */
15874  empty_space.x = window->bounds.x;
15875  empty_space.y = layout->bounds.y;
15876  empty_space.h = panel_padding.y;
15877  empty_space.w = window->bounds.w;
15878  nk_fill_rect(out, empty_space, 0, style->window.background);
15879 
15880  /* fill left empty space */
15881  empty_space.x = window->bounds.x;
15882  empty_space.y = layout->bounds.y;
15883  empty_space.w = panel_padding.x + layout->border;
15884  empty_space.h = layout->bounds.h;
15885  nk_fill_rect(out, empty_space, 0, style->window.background);
15886 
15887  /* fill right empty space */
15888  empty_space.x = layout->bounds.x + layout->bounds.w;
15889  empty_space.y = layout->bounds.y;
15890  empty_space.w = panel_padding.x + layout->border;
15891  empty_space.h = layout->bounds.h;
15892  if (*layout->offset_y == 0 && !(layout->flags & NK_WINDOW_NO_SCROLLBAR))
15893  empty_space.w += scrollbar_size.x;
15894  nk_fill_rect(out, empty_space, 0, style->window.background);
15895 
15896  /* fill bottom empty space */
15897  if (layout->footer_height > 0) {
15898  empty_space.x = window->bounds.x;
15899  empty_space.y = layout->bounds.y + layout->bounds.h;
15900  empty_space.w = window->bounds.w;
15901  empty_space.h = layout->footer_height;
15902  nk_fill_rect(out, empty_space, 0, style->window.background);
15903  }
15904  }
15905 
15906  /* scrollbars */
15907  if (!(layout->flags & NK_WINDOW_NO_SCROLLBAR) &&
15908  !(layout->flags & NK_WINDOW_MINIMIZED) &&
15910  {
15911  struct nk_rect scroll;
15912  int scroll_has_scrolling;
15913  float scroll_target;
15914  float scroll_offset;
15915  float scroll_step;
15916  float scroll_inc;
15917 
15918  /* mouse wheel scrolling */
15919  if (nk_panel_is_sub(layout->type))
15920  {
15921  /* sub-window mouse wheel scrolling */
15922  struct nk_window *root_window = window;
15923  struct nk_panel *root_panel = window->layout;
15924  while (root_panel->parent)
15925  root_panel = root_panel->parent;
15926  while (root_window->parent)
15927  root_window = root_window->parent;
15928 
15929  /* only allow scrolling if parent window is active */
15930  scroll_has_scrolling = 0;
15931  if ((root_window == ctx->active) && layout->has_scrolling) {
15932  /* and panel is being hovered and inside clip rect*/
15933  if (nk_input_is_mouse_hovering_rect(in, layout->bounds) &&
15934  NK_INTERSECT(layout->bounds.x, layout->bounds.y, layout->bounds.w, layout->bounds.h,
15935  root_panel->clip.x, root_panel->clip.y, root_panel->clip.w, root_panel->clip.h))
15936  {
15937  /* deactivate all parent scrolling */
15938  root_panel = window->layout;
15939  while (root_panel->parent) {
15940  root_panel->has_scrolling = nk_false;
15941  root_panel = root_panel->parent;
15942  }
15943  root_panel->has_scrolling = nk_false;
15944  scroll_has_scrolling = nk_true;
15945  }
15946  }
15947  } else if (!nk_panel_is_sub(layout->type)) {
15948  /* window mouse wheel scrolling */
15949  scroll_has_scrolling = (window == ctx->active) && layout->has_scrolling;
15950  if (in && (in->mouse.scroll_delta.y > 0 || in->mouse.scroll_delta.x > 0) && scroll_has_scrolling)
15951  window->scrolled = nk_true;
15952  else window->scrolled = nk_false;
15953  } else scroll_has_scrolling = nk_false;
15954 
15955  {
15956  /* vertical scrollbar */
15957  nk_flags state = 0;
15958  scroll.x = layout->bounds.x + layout->bounds.w + panel_padding.x;
15959  scroll.y = layout->bounds.y;
15960  scroll.w = scrollbar_size.x;
15961  scroll.h = layout->bounds.h;
15962 
15963  scroll_offset = (float)*layout->offset_y;
15964  scroll_step = scroll.h * 0.10f;
15965  scroll_inc = scroll.h * 0.01f;
15966  scroll_target = (float)(int)(layout->at_y - scroll.y);
15967  scroll_offset = nk_do_scrollbarv(&state, out, scroll, scroll_has_scrolling,
15968  scroll_offset, scroll_target, scroll_step, scroll_inc,
15969  &ctx->style.scrollv, in, style->font);
15970  *layout->offset_y = (nk_uint)scroll_offset;
15971  if (in && scroll_has_scrolling)
15972  in->mouse.scroll_delta.y = 0;
15973  }
15974  {
15975  /* horizontal scrollbar */
15976  nk_flags state = 0;
15977  scroll.x = layout->bounds.x;
15978  scroll.y = layout->bounds.y + layout->bounds.h;
15979  scroll.w = layout->bounds.w;
15980  scroll.h = scrollbar_size.y;
15981 
15982  scroll_offset = (float)*layout->offset_x;
15983  scroll_target = (float)(int)(layout->max_x - scroll.x);
15984  scroll_step = layout->max_x * 0.05f;
15985  scroll_inc = layout->max_x * 0.005f;
15986  scroll_offset = nk_do_scrollbarh(&state, out, scroll, scroll_has_scrolling,
15987  scroll_offset, scroll_target, scroll_step, scroll_inc,
15988  &ctx->style.scrollh, in, style->font);
15989  *layout->offset_x = (nk_uint)scroll_offset;
15990  }
15991  }
15992 
15993  /* hide scroll if no user input */
15994  if (window->flags & NK_WINDOW_SCROLL_AUTO_HIDE) {
15995  int has_input = ctx->input.mouse.delta.x != 0 || ctx->input.mouse.delta.y != 0 || ctx->input.mouse.scroll_delta.y != 0;
15996  int is_window_hovered = nk_window_is_hovered(ctx);
15997  int any_item_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED);
15998  if ((!has_input && is_window_hovered) || (!is_window_hovered && !any_item_active))
16000  else window->scrollbar_hiding_timer = 0;
16001  } else window->scrollbar_hiding_timer = 0;
16002 
16003  /* window border */
16004  if (layout->flags & NK_WINDOW_BORDER)
16005  {
16006  struct nk_color border_color = nk_panel_get_border_color(style, layout->type);
16007  const float padding_y = (layout->flags & NK_WINDOW_MINIMIZED)
16008  ? (style->window.border + window->bounds.y + layout->header_height)
16009  : ((layout->flags & NK_WINDOW_DYNAMIC)
16010  ? (layout->bounds.y + layout->bounds.h + layout->footer_height)
16011  : (window->bounds.y + window->bounds.h));
16012  struct nk_rect b = window->bounds;
16013  b.h = padding_y - window->bounds.y;
16014  nk_stroke_rect(out, b, 0, layout->border, border_color);
16015  }
16016 
16017  /* scaler */
16018  if ((layout->flags & NK_WINDOW_SCALABLE) && in && !(layout->flags & NK_WINDOW_MINIMIZED))
16019  {
16020  /* calculate scaler bounds */
16021  struct nk_rect scaler;
16022  scaler.w = scrollbar_size.x;
16023  scaler.h = scrollbar_size.y;
16024  scaler.y = layout->bounds.y + layout->bounds.h;
16025  if (layout->flags & NK_WINDOW_SCALE_LEFT)
16026  scaler.x = layout->bounds.x - panel_padding.x * 0.5f;
16027  else scaler.x = layout->bounds.x + layout->bounds.w + panel_padding.x;
16028  if (layout->flags & NK_WINDOW_NO_SCROLLBAR)
16029  scaler.x -= scaler.w;
16030 
16031  /* draw scaler */
16032  {const struct nk_style_item *item = &style->window.scaler;
16033  if (item->type == NK_STYLE_ITEM_IMAGE)
16034  nk_draw_image(out, scaler, &item->data.image, nk_white);
16035  else {
16036  if (layout->flags & NK_WINDOW_SCALE_LEFT) {
16037  nk_fill_triangle(out, scaler.x, scaler.y, scaler.x,
16038  scaler.y + scaler.h, scaler.x + scaler.w,
16039  scaler.y + scaler.h, item->data.color);
16040  } else {
16041  nk_fill_triangle(out, scaler.x + scaler.w, scaler.y, scaler.x + scaler.w,
16042  scaler.y + scaler.h, scaler.x, scaler.y + scaler.h, item->data.color);
16043  }
16044  }}
16045 
16046  /* do window scaling */
16047  if (!(window->flags & NK_WINDOW_ROM)) {
16048  struct nk_vec2 window_size = style->window.min_size;
16049  int left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
16050  int left_mouse_click_in_scaler = nk_input_has_mouse_click_down_in_rect(in,
16051  NK_BUTTON_LEFT, scaler, nk_true);
16052 
16053  if (left_mouse_down && left_mouse_click_in_scaler) {
16054  float delta_x = in->mouse.delta.x;
16055  if (layout->flags & NK_WINDOW_SCALE_LEFT) {
16056  delta_x = -delta_x;
16057  window->bounds.x += in->mouse.delta.x;
16058  }
16059  /* dragging in x-direction */
16060  if (window->bounds.w + delta_x >= window_size.x) {
16061  if ((delta_x < 0) || (delta_x > 0 && in->mouse.pos.x >= scaler.x)) {
16062  window->bounds.w = window->bounds.w + delta_x;
16063  scaler.x += in->mouse.delta.x;
16064  }
16065  }
16066  /* dragging in y-direction (only possible if static window) */
16067  if (!(layout->flags & NK_WINDOW_DYNAMIC)) {
16068  if (window_size.y < window->bounds.h + in->mouse.delta.y) {
16069  if ((in->mouse.delta.y < 0) || (in->mouse.delta.y > 0 && in->mouse.pos.y >= scaler.y)) {
16070  window->bounds.h = window->bounds.h + in->mouse.delta.y;
16071  scaler.y += in->mouse.delta.y;
16072  }
16073  }
16074  }
16076  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = scaler.x + scaler.w/2.0f;
16077  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = scaler.y + scaler.h/2.0f;
16078  }
16079  }
16080  }
16081  if (!nk_panel_is_sub(layout->type)) {
16082  /* window is hidden so clear command buffer */
16083  if (layout->flags & NK_WINDOW_HIDDEN)
16084  nk_command_buffer_reset(&window->buffer);
16085  /* window is visible and not tab */
16086  else nk_finish(ctx, window);
16087  }
16088 
16089  /* NK_WINDOW_REMOVE_ROM flag was set so remove NK_WINDOW_ROM */
16090  if (layout->flags & NK_WINDOW_REMOVE_ROM) {
16091  layout->flags &= ~(nk_flags)NK_WINDOW_ROM;
16092  layout->flags &= ~(nk_flags)NK_WINDOW_REMOVE_ROM;
16093  }
16094  window->flags = layout->flags;
16095 
16096  /* property garbage collector */
16097  if (window->property.active && window->property.old != window->property.seq &&
16098  window->property.active == window->property.prev) {
16099  nk_zero(&window->property, sizeof(window->property));
16100  } else {
16101  window->property.old = window->property.seq;
16102  window->property.prev = window->property.active;
16103  window->property.seq = 0;
16104  }
16105  /* edit garbage collector */
16106  if (window->edit.active && window->edit.old != window->edit.seq &&
16107  window->edit.active == window->edit.prev) {
16108  nk_zero(&window->edit, sizeof(window->edit));
16109  } else {
16110  window->edit.old = window->edit.seq;
16111  window->edit.prev = window->edit.active;
16112  window->edit.seq = 0;
16113  }
16114  /* contextual garbage collector */
16115  if (window->popup.active_con && window->popup.con_old != window->popup.con_count) {
16116  window->popup.con_count = 0;
16117  window->popup.con_old = 0;
16118  window->popup.active_con = 0;
16119  } else {
16120  window->popup.con_old = window->popup.con_count;
16121  window->popup.con_count = 0;
16122  }
16123  window->popup.combo_count = 0;
16124  /* helper to make sure you have a 'nk_tree_push' for every 'nk_tree_pop' */
16125  NK_ASSERT(!layout->row.tree_depth);
16126 }
16127 
16128 
16129 
16130 
16131 
16132 /* ===============================================================
16133  *
16134  * WINDOW
16135  *
16136  * ===============================================================*/
16137 NK_LIB void*
16138 nk_create_window(struct nk_context *ctx)
16139 {
16140  struct nk_page_element *elem;
16141  elem = nk_create_page_element(ctx);
16142  if (!elem) return 0;
16143  elem->data.win.seq = ctx->seq;
16144  return &elem->data.win;
16145 }
16146 NK_LIB void
16147 nk_free_window(struct nk_context *ctx, struct nk_window *win)
16148 {
16149  /* unlink windows from list */
16150  struct nk_table *it = win->tables;
16151  if (win->popup.win) {
16152  nk_free_window(ctx, win->popup.win);
16153  win->popup.win = 0;
16154  }
16155  win->next = 0;
16156  win->prev = 0;
16157 
16158  while (it) {
16159  /*free window state tables */
16160  struct nk_table *n = it->next;
16161  nk_remove_table(win, it);
16162  nk_free_table(ctx, it);
16163  if (it == win->tables)
16164  win->tables = n;
16165  it = n;
16166  }
16167 
16168  /* link windows into freelist */
16169  {union nk_page_data *pd = NK_CONTAINER_OF(win, union nk_page_data, win);
16170  struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data);
16171  nk_free_page_element(ctx, pe);}
16172 }
16173 NK_LIB struct nk_window*
16174 nk_find_window(struct nk_context *ctx, nk_hash hash, const char *name)
16175 {
16176  struct nk_window *iter;
16177  iter = ctx->begin;
16178  while (iter) {
16179  NK_ASSERT(iter != iter->next);
16180  if (iter->name == hash) {
16181  int max_len = nk_strlen(iter->name_string);
16182  if (!nk_stricmpn(iter->name_string, name, max_len))
16183  return iter;
16184  }
16185  iter = iter->next;
16186  }
16187  return 0;
16188 }
16189 NK_LIB void
16190 nk_insert_window(struct nk_context *ctx, struct nk_window *win,
16191  enum nk_window_insert_location loc)
16192 {
16193  const struct nk_window *iter;
16194  NK_ASSERT(ctx);
16195  NK_ASSERT(win);
16196  if (!win || !ctx) return;
16197 
16198  iter = ctx->begin;
16199  while (iter) {
16200  NK_ASSERT(iter != iter->next);
16201  NK_ASSERT(iter != win);
16202  if (iter == win) return;
16203  iter = iter->next;
16204  }
16205 
16206  if (!ctx->begin) {
16207  win->next = 0;
16208  win->prev = 0;
16209  ctx->begin = win;
16210  ctx->end = win;
16211  ctx->count = 1;
16212  return;
16213  }
16214  if (loc == NK_INSERT_BACK) {
16215  struct nk_window *end;
16216  end = ctx->end;
16217  end->flags |= NK_WINDOW_ROM;
16218  end->next = win;
16219  win->prev = ctx->end;
16220  win->next = 0;
16221  ctx->end = win;
16222  ctx->active = ctx->end;
16224  } else {
16225  /*ctx->end->flags |= NK_WINDOW_ROM;*/
16226  ctx->begin->prev = win;
16227  win->next = ctx->begin;
16228  win->prev = 0;
16229  ctx->begin = win;
16231  }
16232  ctx->count++;
16233 }
16234 NK_LIB void
16235 nk_remove_window(struct nk_context *ctx, struct nk_window *win)
16236 {
16237  if (win == ctx->begin || win == ctx->end) {
16238  if (win == ctx->begin) {
16239  ctx->begin = win->next;
16240  if (win->next)
16241  win->next->prev = 0;
16242  }
16243  if (win == ctx->end) {
16244  ctx->end = win->prev;
16245  if (win->prev)
16246  win->prev->next = 0;
16247  }
16248  } else {
16249  if (win->next)
16250  win->next->prev = win->prev;
16251  if (win->prev)
16252  win->prev->next = win->next;
16253  }
16254  if (win == ctx->active || !ctx->active) {
16255  ctx->active = ctx->end;
16256  if (ctx->end)
16258  }
16259  win->next = 0;
16260  win->prev = 0;
16261  ctx->count--;
16262 }
16263 NK_API int
16264 nk_begin(struct nk_context *ctx, const char *title,
16265  struct nk_rect bounds, nk_flags flags)
16266 {
16267  return nk_begin_titled(ctx, title, title, bounds, flags);
16268 }
16269 NK_API int
16270 nk_begin_titled(struct nk_context *ctx, const char *name, const char *title,
16271  struct nk_rect bounds, nk_flags flags)
16272 {
16273  struct nk_window *win;
16274  struct nk_style *style;
16275  nk_hash name_hash;
16276  int name_len;
16277  int ret = 0;
16278 
16279  NK_ASSERT(ctx);
16280  NK_ASSERT(name);
16281  NK_ASSERT(title);
16282  NK_ASSERT(ctx->style.font && ctx->style.font->width && "if this triggers you forgot to add a font");
16283  NK_ASSERT(!ctx->current && "if this triggers you missed a `nk_end` call");
16284  if (!ctx || ctx->current || !title || !name)
16285  return 0;
16286 
16287  /* find or create window */
16288  style = &ctx->style;
16289  name_len = (int)nk_strlen(name);
16290  name_hash = nk_murmur_hash(name, (int)name_len, NK_WINDOW_TITLE);
16291  win = nk_find_window(ctx, name_hash, name);
16292  if (!win) {
16293  /* create new window */
16294  nk_size name_length = (nk_size)name_len;
16295  win = (struct nk_window*)nk_create_window(ctx);
16296  NK_ASSERT(win);
16297  if (!win) return 0;
16298 
16300  nk_insert_window(ctx, win, NK_INSERT_FRONT);
16301  else nk_insert_window(ctx, win, NK_INSERT_BACK);
16302  nk_command_buffer_init(&win->buffer, &ctx->memory, NK_CLIPPING_ON);
16303 
16304  win->flags = flags;
16305  win->bounds = bounds;
16306  win->name = name_hash;
16307  name_length = NK_MIN(name_length, NK_WINDOW_MAX_NAME-1);
16308  NK_MEMCPY(win->name_string, name, name_length);
16309  win->name_string[name_length] = 0;
16310  win->popup.win = 0;
16311  if (!ctx->active)
16312  ctx->active = win;
16313  } else {
16314  /* update window */
16315  win->flags &= ~(nk_flags)(NK_WINDOW_PRIVATE-1);
16316  win->flags |= flags;
16317  if (!(win->flags & (NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE)))
16318  win->bounds = bounds;
16319  /* If this assert triggers you either:
16320  *
16321  * I.) Have more than one window with the same name or
16322  * II.) You forgot to actually draw the window.
16323  * More specific you did not call `nk_clear` (nk_clear will be
16324  * automatically called for you if you are using one of the
16325  * provided demo backends). */
16326  NK_ASSERT(win->seq != ctx->seq);
16327  win->seq = ctx->seq;
16328  if (!ctx->active && !(win->flags & NK_WINDOW_HIDDEN)) {
16329  ctx->active = win;
16330  ctx->end = win;
16331  }
16332  }
16333  if (win->flags & NK_WINDOW_HIDDEN) {
16334  ctx->current = win;
16335  win->layout = 0;
16336  return 0;
16337  } else nk_start(ctx, win);
16338 
16339  /* window overlapping */
16340  if (!(win->flags & NK_WINDOW_HIDDEN) && !(win->flags & NK_WINDOW_NO_INPUT))
16341  {
16342  int inpanel, ishovered;
16343  struct nk_window *iter = win;
16344  float h = ctx->style.font->height + 2.0f * style->window.header.padding.y +
16345  (2.0f * style->window.header.label_padding.y);
16346  struct nk_rect win_bounds = (!(win->flags & NK_WINDOW_MINIMIZED))?
16347  win->bounds: nk_rect(win->bounds.x, win->bounds.y, win->bounds.w, h);
16348 
16349  /* activate window if hovered and no other window is overlapping this window */
16351  inpanel = inpanel && ctx->input.mouse.buttons[NK_BUTTON_LEFT].clicked;
16352  ishovered = nk_input_is_mouse_hovering_rect(&ctx->input, win_bounds);
16353  if ((win != ctx->active) && ishovered && !ctx->input.mouse.buttons[NK_BUTTON_LEFT].down) {
16354  iter = win->next;
16355  while (iter) {
16356  struct nk_rect iter_bounds = (!(iter->flags & NK_WINDOW_MINIMIZED))?
16357  iter->bounds: nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h);
16358  if (NK_INTERSECT(win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
16359  iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) &&
16360  (!(iter->flags & NK_WINDOW_HIDDEN)))
16361  break;
16362 
16363  if (iter->popup.win && iter->popup.active && !(iter->flags & NK_WINDOW_HIDDEN) &&
16364  NK_INTERSECT(win->bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
16365  iter->popup.win->bounds.x, iter->popup.win->bounds.y,
16366  iter->popup.win->bounds.w, iter->popup.win->bounds.h))
16367  break;
16368  iter = iter->next;
16369  }
16370  }
16371 
16372  /* activate window if clicked */
16373  if (iter && inpanel && (win != ctx->end)) {
16374  iter = win->next;
16375  while (iter) {
16376  /* try to find a panel with higher priority in the same position */
16377  struct nk_rect iter_bounds = (!(iter->flags & NK_WINDOW_MINIMIZED))?
16378  iter->bounds: nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h);
16380  iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) &&
16381  !(iter->flags & NK_WINDOW_HIDDEN))
16382  break;
16383  if (iter->popup.win && iter->popup.active && !(iter->flags & NK_WINDOW_HIDDEN) &&
16384  NK_INTERSECT(win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
16385  iter->popup.win->bounds.x, iter->popup.win->bounds.y,
16386  iter->popup.win->bounds.w, iter->popup.win->bounds.h))
16387  break;
16388  iter = iter->next;
16389  }
16390  }
16391  if (iter && !(win->flags & NK_WINDOW_ROM) && (win->flags & NK_WINDOW_BACKGROUND)) {
16392  win->flags |= (nk_flags)NK_WINDOW_ROM;
16393  iter->flags &= ~(nk_flags)NK_WINDOW_ROM;
16394  ctx->active = iter;
16395  if (!(iter->flags & NK_WINDOW_BACKGROUND)) {
16396  /* current window is active in that position so transfer to top
16397  * at the highest priority in stack */
16398  nk_remove_window(ctx, iter);
16399  nk_insert_window(ctx, iter, NK_INSERT_BACK);
16400  }
16401  } else {
16402  if (!iter && ctx->end != win) {
16403  if (!(win->flags & NK_WINDOW_BACKGROUND)) {
16404  /* current window is active in that position so transfer to top
16405  * at the highest priority in stack */
16406  nk_remove_window(ctx, win);
16407  nk_insert_window(ctx, win, NK_INSERT_BACK);
16408  }
16409  win->flags &= ~(nk_flags)NK_WINDOW_ROM;
16410  ctx->active = win;
16411  }
16412  if (ctx->end != win && !(win->flags & NK_WINDOW_BACKGROUND))
16413  win->flags |= NK_WINDOW_ROM;
16414  }
16415  }
16416  win->layout = (struct nk_panel*)nk_create_panel(ctx);
16417  ctx->current = win;
16418  ret = nk_panel_begin(ctx, title, NK_PANEL_WINDOW);
16419  win->layout->offset_x = &win->scrollbar.x;
16420  win->layout->offset_y = &win->scrollbar.y;
16421  return ret;
16422 }
16423 NK_API void
16424 nk_end(struct nk_context *ctx)
16425 {
16426  struct nk_panel *layout;
16427  NK_ASSERT(ctx);
16428  NK_ASSERT(ctx->current && "if this triggers you forgot to call `nk_begin`");
16429  if (!ctx || !ctx->current)
16430  return;
16431 
16432  layout = ctx->current->layout;
16433  if (!layout || (layout->type == NK_PANEL_WINDOW && (ctx->current->flags & NK_WINDOW_HIDDEN))) {
16434  ctx->current = 0;
16435  return;
16436  }
16437  nk_panel_end(ctx);
16438  nk_free_panel(ctx, ctx->current->layout);
16439  ctx->current = 0;
16440 }
16441 NK_API struct nk_rect
16442 nk_window_get_bounds(const struct nk_context *ctx)
16443 {
16444  NK_ASSERT(ctx);
16445  NK_ASSERT(ctx->current);
16446  if (!ctx || !ctx->current) return nk_rect(0,0,0,0);
16447  return ctx->current->bounds;
16448 }
16449 NK_API struct nk_vec2
16450 nk_window_get_position(const struct nk_context *ctx)
16451 {
16452  NK_ASSERT(ctx);
16453  NK_ASSERT(ctx->current);
16454  if (!ctx || !ctx->current) return nk_vec2(0,0);
16455  return nk_vec2(ctx->current->bounds.x, ctx->current->bounds.y);
16456 }
16457 NK_API struct nk_vec2
16458 nk_window_get_size(const struct nk_context *ctx)
16459 {
16460  NK_ASSERT(ctx);
16461  NK_ASSERT(ctx->current);
16462  if (!ctx || !ctx->current) return nk_vec2(0,0);
16463  return nk_vec2(ctx->current->bounds.w, ctx->current->bounds.h);
16464 }
16465 NK_API float
16466 nk_window_get_width(const struct nk_context *ctx)
16467 {
16468  NK_ASSERT(ctx);
16469  NK_ASSERT(ctx->current);
16470  if (!ctx || !ctx->current) return 0;
16471  return ctx->current->bounds.w;
16472 }
16473 NK_API float
16474 nk_window_get_height(const struct nk_context *ctx)
16475 {
16476  NK_ASSERT(ctx);
16477  NK_ASSERT(ctx->current);
16478  if (!ctx || !ctx->current) return 0;
16479  return ctx->current->bounds.h;
16480 }
16481 NK_API struct nk_rect
16483 {
16484  NK_ASSERT(ctx);
16485  NK_ASSERT(ctx->current);
16486  if (!ctx || !ctx->current) return nk_rect(0,0,0,0);
16487  return ctx->current->layout->clip;
16488 }
16489 NK_API struct nk_vec2
16491 {
16492  NK_ASSERT(ctx);
16493  NK_ASSERT(ctx->current);
16494  NK_ASSERT(ctx->current->layout);
16495  if (!ctx || !ctx->current) return nk_vec2(0,0);
16496  return nk_vec2(ctx->current->layout->clip.x, ctx->current->layout->clip.y);
16497 }
16498 NK_API struct nk_vec2
16500 {
16501  NK_ASSERT(ctx);
16502  NK_ASSERT(ctx->current);
16503  NK_ASSERT(ctx->current->layout);
16504  if (!ctx || !ctx->current) return nk_vec2(0,0);
16505  return nk_vec2(ctx->current->layout->clip.x + ctx->current->layout->clip.w,
16507 }
16508 NK_API struct nk_vec2
16510 {
16511  NK_ASSERT(ctx);
16512  NK_ASSERT(ctx->current);
16513  NK_ASSERT(ctx->current->layout);
16514  if (!ctx || !ctx->current) return nk_vec2(0,0);
16515  return nk_vec2(ctx->current->layout->clip.w, ctx->current->layout->clip.h);
16516 }
16517 NK_API struct nk_command_buffer*
16519 {
16520  NK_ASSERT(ctx);
16521  NK_ASSERT(ctx->current);
16522  NK_ASSERT(ctx->current->layout);
16523  if (!ctx || !ctx->current) return 0;
16524  return &ctx->current->buffer;
16525 }
16526 NK_API struct nk_panel*
16528 {
16529  NK_ASSERT(ctx);
16530  NK_ASSERT(ctx->current);
16531  if (!ctx || !ctx->current) return 0;
16532  return ctx->current->layout;
16533 }
16534 NK_API void
16536 {
16537  struct nk_window *win;
16538  NK_ASSERT(ctx);
16539  NK_ASSERT(ctx->current);
16540  if (!ctx || !ctx->current)
16541  return ;
16542  win = ctx->current;
16543  if (offset_x)
16544  *offset_x = win->scrollbar.x;
16545  if (offset_y)
16546  *offset_y = win->scrollbar.y;
16547 }
16548 NK_API int
16549 nk_window_has_focus(const struct nk_context *ctx)
16550 {
16551  NK_ASSERT(ctx);
16552  NK_ASSERT(ctx->current);
16553  NK_ASSERT(ctx->current->layout);
16554  if (!ctx || !ctx->current) return 0;
16555  return ctx->current == ctx->active;
16556 }
16557 NK_API int
16559 {
16560  NK_ASSERT(ctx);
16561  NK_ASSERT(ctx->current);
16562  if (!ctx || !ctx->current) return 0;
16564  return 0;
16566 }
16567 NK_API int
16569 {
16570  struct nk_window *iter;
16571  NK_ASSERT(ctx);
16572  if (!ctx) return 0;
16573  iter = ctx->begin;
16574  while (iter) {
16575  /* check if window is being hovered */
16576  if(!(iter->flags & NK_WINDOW_HIDDEN)) {
16577  /* check if window popup is being hovered */
16578  if (iter->popup.active && iter->popup.win && nk_input_is_mouse_hovering_rect(&ctx->input, iter->popup.win->bounds))
16579  return 1;
16580 
16581  if (iter->flags & NK_WINDOW_MINIMIZED) {
16582  struct nk_rect header = iter->bounds;
16583  header.h = ctx->style.font->height + 2 * ctx->style.window.header.padding.y;
16584  if (nk_input_is_mouse_hovering_rect(&ctx->input, header))
16585  return 1;
16586  } else if (nk_input_is_mouse_hovering_rect(&ctx->input, iter->bounds)) {
16587  return 1;
16588  }
16589  }
16590  iter = iter->next;
16591  }
16592  return 0;
16593 }
16594 NK_API int
16596 {
16597  int any_hovered = nk_window_is_any_hovered(ctx);
16598  int any_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED);
16599  return any_hovered || any_active;
16600 }
16601 NK_API int
16602 nk_window_is_collapsed(struct nk_context *ctx, const char *name)
16603 {
16604  int title_len;
16605  nk_hash title_hash;
16606  struct nk_window *win;
16607  NK_ASSERT(ctx);
16608  if (!ctx) return 0;
16609 
16610  title_len = (int)nk_strlen(name);
16611  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16612  win = nk_find_window(ctx, title_hash, name);
16613  if (!win) return 0;
16614  return win->flags & NK_WINDOW_MINIMIZED;
16615 }
16616 NK_API int
16617 nk_window_is_closed(struct nk_context *ctx, const char *name)
16618 {
16619  int title_len;
16620  nk_hash title_hash;
16621  struct nk_window *win;
16622  NK_ASSERT(ctx);
16623  if (!ctx) return 1;
16624 
16625  title_len = (int)nk_strlen(name);
16626  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16627  win = nk_find_window(ctx, title_hash, name);
16628  if (!win) return 1;
16629  return (win->flags & NK_WINDOW_CLOSED);
16630 }
16631 NK_API int
16632 nk_window_is_hidden(struct nk_context *ctx, const char *name)
16633 {
16634  int title_len;
16635  nk_hash title_hash;
16636  struct nk_window *win;
16637  NK_ASSERT(ctx);
16638  if (!ctx) return 1;
16639 
16640  title_len = (int)nk_strlen(name);
16641  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16642  win = nk_find_window(ctx, title_hash, name);
16643  if (!win) return 1;
16644  return (win->flags & NK_WINDOW_HIDDEN);
16645 }
16646 NK_API int
16647 nk_window_is_active(struct nk_context *ctx, const char *name)
16648 {
16649  int title_len;
16650  nk_hash title_hash;
16651  struct nk_window *win;
16652  NK_ASSERT(ctx);
16653  if (!ctx) return 0;
16654 
16655  title_len = (int)nk_strlen(name);
16656  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16657  win = nk_find_window(ctx, title_hash, name);
16658  if (!win) return 0;
16659  return win == ctx->active;
16660 }
16661 NK_API struct nk_window*
16662 nk_window_find(struct nk_context *ctx, const char *name)
16663 {
16664  int title_len;
16665  nk_hash title_hash;
16666  title_len = (int)nk_strlen(name);
16667  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16668  return nk_find_window(ctx, title_hash, name);
16669 }
16670 NK_API void
16671 nk_window_close(struct nk_context *ctx, const char *name)
16672 {
16673  struct nk_window *win;
16674  NK_ASSERT(ctx);
16675  if (!ctx) return;
16676  win = nk_window_find(ctx, name);
16677  if (!win) return;
16678  NK_ASSERT(ctx->current != win && "You cannot close a currently active window");
16679  if (ctx->current == win) return;
16680  win->flags |= NK_WINDOW_HIDDEN;
16681  win->flags |= NK_WINDOW_CLOSED;
16682 }
16683 NK_API void
16685  const char *name, struct nk_rect bounds)
16686 {
16687  struct nk_window *win;
16688  NK_ASSERT(ctx);
16689  if (!ctx) return;
16690  win = nk_window_find(ctx, name);
16691  if (!win) return;
16692  NK_ASSERT(ctx->current != win && "You cannot update a currently in procecss window");
16693  win->bounds = bounds;
16694 }
16695 NK_API void
16697  const char *name, struct nk_vec2 pos)
16698 {
16699  struct nk_window *win = nk_window_find(ctx, name);
16700  if (!win) return;
16701  win->bounds.x = pos.x;
16702  win->bounds.y = pos.y;
16703 }
16704 NK_API void
16706  const char *name, struct nk_vec2 size)
16707 {
16708  struct nk_window *win = nk_window_find(ctx, name);
16709  if (!win) return;
16710  win->bounds.w = size.x;
16711  win->bounds.h = size.y;
16712 }
16713 NK_API void
16714 nk_window_set_scroll(struct nk_context *ctx, nk_uint offset_x, nk_uint offset_y)
16715 {
16716  struct nk_window *win;
16717  NK_ASSERT(ctx);
16718  NK_ASSERT(ctx->current);
16719  if (!ctx || !ctx->current)
16720  return;
16721  win = ctx->current;
16722  win->scrollbar.x = offset_x;
16723  win->scrollbar.y = offset_y;
16724 }
16725 NK_API void
16726 nk_window_collapse(struct nk_context *ctx, const char *name,
16727  enum nk_collapse_states c)
16728 {
16729  int title_len;
16730  nk_hash title_hash;
16731  struct nk_window *win;
16732  NK_ASSERT(ctx);
16733  if (!ctx) return;
16734 
16735  title_len = (int)nk_strlen(name);
16736  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16737  win = nk_find_window(ctx, title_hash, name);
16738  if (!win) return;
16739  if (c == NK_MINIMIZED)
16740  win->flags |= NK_WINDOW_MINIMIZED;
16741  else win->flags &= ~(nk_flags)NK_WINDOW_MINIMIZED;
16742 }
16743 NK_API void
16744 nk_window_collapse_if(struct nk_context *ctx, const char *name,
16745  enum nk_collapse_states c, int cond)
16746 {
16747  NK_ASSERT(ctx);
16748  if (!ctx || !cond) return;
16750 }
16751 NK_API void
16752 nk_window_show(struct nk_context *ctx, const char *name, enum nk_show_states s)
16753 {
16754  int title_len;
16755  nk_hash title_hash;
16756  struct nk_window *win;
16757  NK_ASSERT(ctx);
16758  if (!ctx) return;
16759 
16760  title_len = (int)nk_strlen(name);
16761  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16762  win = nk_find_window(ctx, title_hash, name);
16763  if (!win) return;
16764  if (s == NK_HIDDEN) {
16765  win->flags |= NK_WINDOW_HIDDEN;
16766  } else win->flags &= ~(nk_flags)NK_WINDOW_HIDDEN;
16767 }
16768 NK_API void
16769 nk_window_show_if(struct nk_context *ctx, const char *name,
16770  enum nk_show_states s, int cond)
16771 {
16772  NK_ASSERT(ctx);
16773  if (!ctx || !cond) return;
16774  nk_window_show(ctx, name, s);
16775 }
16776 
16777 NK_API void
16778 nk_window_set_focus(struct nk_context *ctx, const char *name)
16779 {
16780  int title_len;
16781  nk_hash title_hash;
16782  struct nk_window *win;
16783  NK_ASSERT(ctx);
16784  if (!ctx) return;
16785 
16786  title_len = (int)nk_strlen(name);
16787  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16788  win = nk_find_window(ctx, title_hash, name);
16789  if (win && ctx->end != win) {
16790  nk_remove_window(ctx, win);
16791  nk_insert_window(ctx, win, NK_INSERT_BACK);
16792  }
16793  ctx->active = win;
16794 }
16795 
16796 
16797 
16798 
16799 /* ===============================================================
16800  *
16801  * POPUP
16802  *
16803  * ===============================================================*/
16804 NK_API int
16805 nk_popup_begin(struct nk_context *ctx, enum nk_popup_type type,
16806  const char *title, nk_flags flags, struct nk_rect rect)
16807 {
16808  struct nk_window *popup;
16809  struct nk_window *win;
16810  struct nk_panel *panel;
16811 
16812  int title_len;
16813  nk_hash title_hash;
16814  nk_size allocated;
16815 
16816  NK_ASSERT(ctx);
16817  NK_ASSERT(title);
16818  NK_ASSERT(ctx->current);
16819  NK_ASSERT(ctx->current->layout);
16820  if (!ctx || !ctx->current || !ctx->current->layout)
16821  return 0;
16822 
16823  win = ctx->current;
16824  panel = win->layout;
16825  NK_ASSERT(!(panel->type & NK_PANEL_SET_POPUP) && "popups are not allowed to have popups");
16826  (void)panel;
16827  title_len = (int)nk_strlen(title);
16828  title_hash = nk_murmur_hash(title, (int)title_len, NK_PANEL_POPUP);
16829 
16830  popup = win->popup.win;
16831  if (!popup) {
16832  popup = (struct nk_window*)nk_create_window(ctx);
16833  popup->parent = win;
16834  win->popup.win = popup;
16835  win->popup.active = 0;
16836  win->popup.type = NK_PANEL_POPUP;
16837  }
16838 
16839  /* make sure we have correct popup */
16840  if (win->popup.name != title_hash) {
16841  if (!win->popup.active) {
16842  nk_zero(popup, sizeof(*popup));
16843  win->popup.name = title_hash;
16844  win->popup.active = 1;
16845  win->popup.type = NK_PANEL_POPUP;
16846  } else return 0;
16847  }
16848 
16849  /* popup position is local to window */
16850  ctx->current = popup;
16851  rect.x += win->layout->clip.x;
16852  rect.y += win->layout->clip.y;
16853 
16854  /* setup popup data */
16855  popup->parent = win;
16856  popup->bounds = rect;
16857  popup->seq = ctx->seq;
16858  popup->layout = (struct nk_panel*)nk_create_panel(ctx);
16859  popup->flags = flags;
16860  popup->flags |= NK_WINDOW_BORDER;
16861  if (type == NK_POPUP_DYNAMIC)
16862  popup->flags |= NK_WINDOW_DYNAMIC;
16863 
16864  popup->buffer = win->buffer;
16865  nk_start_popup(ctx, win);
16866  allocated = ctx->memory.allocated;
16867  nk_push_scissor(&popup->buffer, nk_null_rect);
16868 
16869  if (nk_panel_begin(ctx, title, NK_PANEL_POPUP)) {
16870  /* popup is running therefore invalidate parent panels */
16871  struct nk_panel *root;
16872  root = win->layout;
16873  while (root) {
16874  root->flags |= NK_WINDOW_ROM;
16875  root->flags &= ~(nk_flags)NK_WINDOW_REMOVE_ROM;
16876  root = root->parent;
16877  }
16878  win->popup.active = 1;
16879  popup->layout->offset_x = &popup->scrollbar.x;
16880  popup->layout->offset_y = &popup->scrollbar.y;
16881  popup->layout->parent = win->layout;
16882  return 1;
16883  } else {
16884  /* popup was closed/is invalid so cleanup */
16885  struct nk_panel *root;
16886  root = win->layout;
16887  while (root) {
16888  root->flags |= NK_WINDOW_REMOVE_ROM;
16889  root = root->parent;
16890  }
16891  win->popup.buf.active = 0;
16892  win->popup.active = 0;
16893  ctx->memory.allocated = allocated;
16894  ctx->current = win;
16895  nk_free_panel(ctx, popup->layout);
16896  popup->layout = 0;
16897  return 0;
16898  }
16899 }
16900 NK_LIB int
16901 nk_nonblock_begin(struct nk_context *ctx,
16902  nk_flags flags, struct nk_rect body, struct nk_rect header,
16903  enum nk_panel_type panel_type)
16904 {
16905  struct nk_window *popup;
16906  struct nk_window *win;
16907  struct nk_panel *panel;
16908  int is_active = nk_true;
16909 
16910  NK_ASSERT(ctx);
16911  NK_ASSERT(ctx->current);
16912  NK_ASSERT(ctx->current->layout);
16913  if (!ctx || !ctx->current || !ctx->current->layout)
16914  return 0;
16915 
16916  /* popups cannot have popups */
16917  win = ctx->current;
16918  panel = win->layout;
16919  NK_ASSERT(!(panel->type & NK_PANEL_SET_POPUP));
16920  (void)panel;
16921  popup = win->popup.win;
16922  if (!popup) {
16923  /* create window for nonblocking popup */
16924  popup = (struct nk_window*)nk_create_window(ctx);
16925  popup->parent = win;
16926  win->popup.win = popup;
16927  win->popup.type = panel_type;
16928  nk_command_buffer_init(&popup->buffer, &ctx->memory, NK_CLIPPING_ON);
16929  } else {
16930  /* close the popup if user pressed outside or in the header */
16931  int pressed, in_body, in_header;
16932 #ifdef NK_BUTTON_TRIGGER_ON_RELEASE
16934 #else
16936 #endif
16937  in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body);
16938  in_header = nk_input_is_mouse_hovering_rect(&ctx->input, header);
16939  if (pressed && (!in_body || in_header))
16940  is_active = nk_false;
16941  }
16942  win->popup.header = header;
16943 
16944  if (!is_active) {
16945  /* remove read only mode from all parent panels */
16946  struct nk_panel *root = win->layout;
16947  while (root) {
16948  root->flags |= NK_WINDOW_REMOVE_ROM;
16949  root = root->parent;
16950  }
16951  return is_active;
16952  }
16953  popup->bounds = body;
16954  popup->parent = win;
16955  popup->layout = (struct nk_panel*)nk_create_panel(ctx);
16956  popup->flags = flags;
16957  popup->flags |= NK_WINDOW_BORDER;
16958  popup->flags |= NK_WINDOW_DYNAMIC;
16959  popup->seq = ctx->seq;
16960  win->popup.active = 1;
16961  NK_ASSERT(popup->layout);
16962 
16963  nk_start_popup(ctx, win);
16964  popup->buffer = win->buffer;
16965  nk_push_scissor(&popup->buffer, nk_null_rect);
16966  ctx->current = popup;
16967 
16968  nk_panel_begin(ctx, 0, panel_type);
16969  win->buffer = popup->buffer;
16970  popup->layout->parent = win->layout;
16971  popup->layout->offset_x = &popup->scrollbar.x;
16972  popup->layout->offset_y = &popup->scrollbar.y;
16973 
16974  /* set read only mode to all parent panels */
16975  {struct nk_panel *root;
16976  root = win->layout;
16977  while (root) {
16978  root->flags |= NK_WINDOW_ROM;
16979  root = root->parent;
16980  }}
16981  return is_active;
16982 }
16983 NK_API void
16984 nk_popup_close(struct nk_context *ctx)
16985 {
16986  struct nk_window *popup;
16987  NK_ASSERT(ctx);
16988  if (!ctx || !ctx->current) return;
16989 
16990  popup = ctx->current;
16991  NK_ASSERT(popup->parent);
16992  NK_ASSERT(popup->layout->type & NK_PANEL_SET_POPUP);
16993  popup->flags |= NK_WINDOW_HIDDEN;
16994 }
16995 NK_API void
16996 nk_popup_end(struct nk_context *ctx)
16997 {
16998  struct nk_window *win;
16999  struct nk_window *popup;
17000 
17001  NK_ASSERT(ctx);
17002  NK_ASSERT(ctx->current);
17003  NK_ASSERT(ctx->current->layout);
17004  if (!ctx || !ctx->current || !ctx->current->layout)
17005  return;
17006 
17007  popup = ctx->current;
17008  if (!popup->parent) return;
17009  win = popup->parent;
17010  if (popup->flags & NK_WINDOW_HIDDEN) {
17011  struct nk_panel *root;
17012  root = win->layout;
17013  while (root) {
17014  root->flags |= NK_WINDOW_REMOVE_ROM;
17015  root = root->parent;
17016  }
17017  win->popup.active = 0;
17018  }
17019  nk_push_scissor(&popup->buffer, nk_null_rect);
17020  nk_end(ctx);
17021 
17022  win->buffer = popup->buffer;
17023  nk_finish_popup(ctx, win);
17024  ctx->current = win;
17025  nk_push_scissor(&win->buffer, win->layout->clip);
17026 }
17027 NK_API void
17029 {
17030  struct nk_window *popup;
17031 
17032  NK_ASSERT(ctx);
17033  NK_ASSERT(ctx->current);
17034  NK_ASSERT(ctx->current->layout);
17035  if (!ctx || !ctx->current || !ctx->current->layout)
17036  return;
17037 
17038  popup = ctx->current;
17039  if (offset_x)
17040  *offset_x = popup->scrollbar.x;
17041  if (offset_y)
17042  *offset_y = popup->scrollbar.y;
17043 }
17044 NK_API void
17045 nk_popup_set_scroll(struct nk_context *ctx, nk_uint offset_x, nk_uint offset_y)
17046 {
17047  struct nk_window *popup;
17048 
17049  NK_ASSERT(ctx);
17050  NK_ASSERT(ctx->current);
17051  NK_ASSERT(ctx->current->layout);
17052  if (!ctx || !ctx->current || !ctx->current->layout)
17053  return;
17054 
17055  popup = ctx->current;
17056  popup->scrollbar.x = offset_x;
17057  popup->scrollbar.y = offset_y;
17058 }
17059 
17060 
17061 
17062 
17063 /* ==============================================================
17064  *
17065  * CONTEXTUAL
17066  *
17067  * ===============================================================*/
17068 NK_API int
17069 nk_contextual_begin(struct nk_context *ctx, nk_flags flags, struct nk_vec2 size,
17070  struct nk_rect trigger_bounds)
17071 {
17072  struct nk_window *win;
17073  struct nk_window *popup;
17074  struct nk_rect body;
17075 
17076  NK_STORAGE const struct nk_rect null_rect = {-1,-1,0,0};
17077  int is_clicked = 0;
17078  int is_open = 0;
17079  int ret = 0;
17080 
17081  NK_ASSERT(ctx);
17082  NK_ASSERT(ctx->current);
17083  NK_ASSERT(ctx->current->layout);
17084  if (!ctx || !ctx->current || !ctx->current->layout)
17085  return 0;
17086 
17087  win = ctx->current;
17088  ++win->popup.con_count;
17089  if (ctx->current != ctx->active)
17090  return 0;
17091 
17092  /* check if currently active contextual is active */
17093  popup = win->popup.win;
17094  is_open = (popup && win->popup.type == NK_PANEL_CONTEXTUAL);
17095  is_clicked = nk_input_mouse_clicked(&ctx->input, NK_BUTTON_RIGHT, trigger_bounds);
17096  if (win->popup.active_con && win->popup.con_count != win->popup.active_con)
17097  return 0;
17098  if (!is_open && win->popup.active_con)
17099  win->popup.active_con = 0;
17100  if ((!is_open && !is_clicked))
17101  return 0;
17102 
17103  /* calculate contextual position on click */
17104  win->popup.active_con = win->popup.con_count;
17105  if (is_clicked) {
17106  body.x = ctx->input.mouse.pos.x;
17107  body.y = ctx->input.mouse.pos.y;
17108  } else {
17109  body.x = popup->bounds.x;
17110  body.y = popup->bounds.y;
17111  }
17112  body.w = size.x;
17113  body.h = size.y;
17114 
17115  /* start nonblocking contextual popup */
17116  ret = nk_nonblock_begin(ctx, flags|NK_WINDOW_NO_SCROLLBAR, body,
17117  null_rect, NK_PANEL_CONTEXTUAL);
17118  if (ret) win->popup.type = NK_PANEL_CONTEXTUAL;
17119  else {
17120  win->popup.active_con = 0;
17121  win->popup.type = NK_PANEL_NONE;
17122  if (win->popup.win)
17123  win->popup.win->flags = 0;
17124  }
17125  return ret;
17126 }
17127 NK_API int
17128 nk_contextual_item_text(struct nk_context *ctx, const char *text, int len,
17129  nk_flags alignment)
17130 {
17131  struct nk_window *win;
17132  const struct nk_input *in;
17133  const struct nk_style *style;
17134 
17135  struct nk_rect bounds;
17136  enum nk_widget_layout_states state;
17137 
17138  NK_ASSERT(ctx);
17139  NK_ASSERT(ctx->current);
17140  NK_ASSERT(ctx->current->layout);
17141  if (!ctx || !ctx->current || !ctx->current->layout)
17142  return 0;
17143 
17144  win = ctx->current;
17145  style = &ctx->style;
17146  state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
17147  if (!state) return nk_false;
17148 
17149  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17150  if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds,
17151  text, len, alignment, NK_BUTTON_DEFAULT, &style->contextual_button, in, style->font)) {
17153  return nk_true;
17154  }
17155  return nk_false;
17156 }
17157 NK_API int
17158 nk_contextual_item_label(struct nk_context *ctx, const char *label, nk_flags align)
17159 {
17160  return nk_contextual_item_text(ctx, label, nk_strlen(label), align);
17161 }
17162 NK_API int
17164  const char *text, int len, nk_flags align)
17165 {
17166  struct nk_window *win;
17167  const struct nk_input *in;
17168  const struct nk_style *style;
17169 
17170  struct nk_rect bounds;
17171  enum nk_widget_layout_states state;
17172 
17173  NK_ASSERT(ctx);
17174  NK_ASSERT(ctx->current);
17175  NK_ASSERT(ctx->current->layout);
17176  if (!ctx || !ctx->current || !ctx->current->layout)
17177  return 0;
17178 
17179  win = ctx->current;
17180  style = &ctx->style;
17181  state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
17182  if (!state) return nk_false;
17183 
17184  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17185  if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer, bounds,
17186  img, text, len, align, NK_BUTTON_DEFAULT, &style->contextual_button, style->font, in)){
17188  return nk_true;
17189  }
17190  return nk_false;
17191 }
17192 NK_API int
17194  const char *label, nk_flags align)
17195 {
17196  return nk_contextual_item_image_text(ctx, img, label, nk_strlen(label), align);
17197 }
17198 NK_API int
17200  const char *text, int len, nk_flags align)
17201 {
17202  struct nk_window *win;
17203  const struct nk_input *in;
17204  const struct nk_style *style;
17205 
17206  struct nk_rect bounds;
17207  enum nk_widget_layout_states state;
17208 
17209  NK_ASSERT(ctx);
17210  NK_ASSERT(ctx->current);
17211  NK_ASSERT(ctx->current->layout);
17212  if (!ctx || !ctx->current || !ctx->current->layout)
17213  return 0;
17214 
17215  win = ctx->current;
17216  style = &ctx->style;
17217  state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
17218  if (!state) return nk_false;
17219 
17220  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17221  if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds,
17222  symbol, text, len, align, NK_BUTTON_DEFAULT, &style->contextual_button, style->font, in)) {
17224  return nk_true;
17225  }
17226  return nk_false;
17227 }
17228 NK_API int
17230  const char *text, nk_flags align)
17231 {
17232  return nk_contextual_item_symbol_text(ctx, symbol, text, nk_strlen(text), align);
17233 }
17234 NK_API void
17236 {
17237  NK_ASSERT(ctx);
17238  NK_ASSERT(ctx->current);
17239  NK_ASSERT(ctx->current->layout);
17240  if (!ctx || !ctx->current || !ctx->current->layout) return;
17242 }
17243 NK_API void
17245 {
17246  struct nk_window *popup;
17247  struct nk_panel *panel;
17248  NK_ASSERT(ctx);
17249  NK_ASSERT(ctx->current);
17250  if (!ctx || !ctx->current) return;
17251 
17252  popup = ctx->current;
17253  panel = popup->layout;
17254  NK_ASSERT(popup->parent);
17255  NK_ASSERT(panel->type & NK_PANEL_SET_POPUP);
17256  if (panel->flags & NK_WINDOW_DYNAMIC) {
17257  /* Close behavior
17258  This is a bit of a hack solution since we do not know before we end our popup
17259  how big it will be. We therefore do not directly know when a
17260  click outside the non-blocking popup must close it at that direct frame.
17261  Instead it will be closed in the next frame.*/
17262  struct nk_rect body = {0,0,0,0};
17263  if (panel->at_y < (panel->bounds.y + panel->bounds.h)) {
17264  struct nk_vec2 padding = nk_panel_get_padding(&ctx->style, panel->type);
17265  body = panel->bounds;
17266  body.y = (panel->at_y + panel->footer_height + panel->border + padding.y + panel->row.height);
17267  body.h = (panel->bounds.y + panel->bounds.h) - body.y;
17268  }
17270  int in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body);
17271  if (pressed && in_body)
17272  popup->flags |= NK_WINDOW_HIDDEN;
17273  }
17274  }
17275  if (popup->flags & NK_WINDOW_HIDDEN)
17276  popup->seq = 0;
17277  nk_popup_end(ctx);
17278  return;
17279 }
17280 
17281 
17282 
17283 
17284 
17285 /* ===============================================================
17286  *
17287  * MENU
17288  *
17289  * ===============================================================*/
17290 NK_API void
17292 {
17293  struct nk_panel *layout;
17294  NK_ASSERT(ctx);
17295  NK_ASSERT(ctx->current);
17296  NK_ASSERT(ctx->current->layout);
17297  if (!ctx || !ctx->current || !ctx->current->layout)
17298  return;
17299 
17300  layout = ctx->current->layout;
17301  NK_ASSERT(layout->at_y == layout->bounds.y);
17302  /* if this assert triggers you allocated space between nk_begin and nk_menubar_begin.
17303  If you want a menubar the first nuklear function after `nk_begin` has to be a
17304  `nk_menubar_begin` call. Inside the menubar you then have to allocate space for
17305  widgets (also supports multiple rows).
17306  Example:
17307  if (nk_begin(...)) {
17308  nk_menubar_begin(...);
17309  nk_layout_xxxx(...);
17310  nk_button(...);
17311  nk_layout_xxxx(...);
17312  nk_button(...);
17313  nk_menubar_end(...);
17314  }
17315  nk_end(...);
17316  */
17317  if (layout->flags & NK_WINDOW_HIDDEN || layout->flags & NK_WINDOW_MINIMIZED)
17318  return;
17319 
17320  layout->menu.x = layout->at_x;
17321  layout->menu.y = layout->at_y + layout->row.height;
17322  layout->menu.w = layout->bounds.w;
17323  layout->menu.offset.x = *layout->offset_x;
17324  layout->menu.offset.y = *layout->offset_y;
17325  *layout->offset_y = 0;
17326 }
17327 NK_API void
17328 nk_menubar_end(struct nk_context *ctx)
17329 {
17330  struct nk_window *win;
17331  struct nk_panel *layout;
17332  struct nk_command_buffer *out;
17333 
17334  NK_ASSERT(ctx);
17335  NK_ASSERT(ctx->current);
17336  NK_ASSERT(ctx->current->layout);
17337  if (!ctx || !ctx->current || !ctx->current->layout)
17338  return;
17339 
17340  win = ctx->current;
17341  out = &win->buffer;
17342  layout = win->layout;
17343  if (layout->flags & NK_WINDOW_HIDDEN || layout->flags & NK_WINDOW_MINIMIZED)
17344  return;
17345 
17346  layout->menu.h = layout->at_y - layout->menu.y;
17347  layout->bounds.y += layout->menu.h + ctx->style.window.spacing.y + layout->row.height;
17348  layout->bounds.h -= layout->menu.h + ctx->style.window.spacing.y + layout->row.height;
17349 
17350  *layout->offset_x = layout->menu.offset.x;
17351  *layout->offset_y = layout->menu.offset.y;
17352  layout->at_y = layout->bounds.y - layout->row.height;
17353 
17354  layout->clip.y = layout->bounds.y;
17355  layout->clip.h = layout->bounds.h;
17356  nk_push_scissor(out, layout->clip);
17357 }
17358 NK_INTERN int
17359 nk_menu_begin(struct nk_context *ctx, struct nk_window *win,
17360  const char *id, int is_clicked, struct nk_rect header, struct nk_vec2 size)
17361 {
17362  int is_open = 0;
17363  int is_active = 0;
17364  struct nk_rect body;
17365  struct nk_window *popup;
17366  nk_hash hash = nk_murmur_hash(id, (int)nk_strlen(id), NK_PANEL_MENU);
17367 
17368  NK_ASSERT(ctx);
17369  NK_ASSERT(ctx->current);
17370  NK_ASSERT(ctx->current->layout);
17371  if (!ctx || !ctx->current || !ctx->current->layout)
17372  return 0;
17373 
17374  body.x = header.x;
17375  body.w = size.x;
17376  body.y = header.y + header.h;
17377  body.h = size.y;
17378 
17379  popup = win->popup.win;
17380  is_open = popup ? nk_true : nk_false;
17381  is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_MENU);
17382  if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
17383  (!is_open && !is_active && !is_clicked)) return 0;
17384  if (!nk_nonblock_begin(ctx, NK_WINDOW_NO_SCROLLBAR, body, header, NK_PANEL_MENU))
17385  return 0;
17386 
17387  win->popup.type = NK_PANEL_MENU;
17388  win->popup.name = hash;
17389  return 1;
17390 }
17391 NK_API int
17392 nk_menu_begin_text(struct nk_context *ctx, const char *title, int len,
17393  nk_flags align, struct nk_vec2 size)
17394 {
17395  struct nk_window *win;
17396  const struct nk_input *in;
17397  struct nk_rect header;
17398  int is_clicked = nk_false;
17399  nk_flags state;
17400 
17401  NK_ASSERT(ctx);
17402  NK_ASSERT(ctx->current);
17403  NK_ASSERT(ctx->current->layout);
17404  if (!ctx || !ctx->current || !ctx->current->layout)
17405  return 0;
17406 
17407  win = ctx->current;
17408  state = nk_widget(&header, ctx);
17409  if (!state) return 0;
17410  in = (state == NK_WIDGET_ROM || win->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17411  if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, header,
17412  title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font))
17413  is_clicked = nk_true;
17414  return nk_menu_begin(ctx, win, title, is_clicked, header, size);
17415 }
17417  const char *text, nk_flags align, struct nk_vec2 size)
17418 {
17419  return nk_menu_begin_text(ctx, text, nk_strlen(text), align, size);
17420 }
17421 NK_API int
17422 nk_menu_begin_image(struct nk_context *ctx, const char *id, struct nk_image img,
17423  struct nk_vec2 size)
17424 {
17425  struct nk_window *win;
17426  struct nk_rect header;
17427  const struct nk_input *in;
17428  int is_clicked = nk_false;
17429  nk_flags state;
17430 
17431  NK_ASSERT(ctx);
17432  NK_ASSERT(ctx->current);
17433  NK_ASSERT(ctx->current->layout);
17434  if (!ctx || !ctx->current || !ctx->current->layout)
17435  return 0;
17436 
17437  win = ctx->current;
17438  state = nk_widget(&header, ctx);
17439  if (!state) return 0;
17440  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17441  if (nk_do_button_image(&ctx->last_widget_state, &win->buffer, header,
17442  img, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in))
17443  is_clicked = nk_true;
17444  return nk_menu_begin(ctx, win, id, is_clicked, header, size);
17445 }
17446 NK_API int
17447 nk_menu_begin_symbol(struct nk_context *ctx, const char *id,
17448  enum nk_symbol_type sym, struct nk_vec2 size)
17449 {
17450  struct nk_window *win;
17451  const struct nk_input *in;
17452  struct nk_rect header;
17453  int is_clicked = nk_false;
17454  nk_flags state;
17455 
17456  NK_ASSERT(ctx);
17457  NK_ASSERT(ctx->current);
17458  NK_ASSERT(ctx->current->layout);
17459  if (!ctx || !ctx->current || !ctx->current->layout)
17460  return 0;
17461 
17462  win = ctx->current;
17463  state = nk_widget(&header, ctx);
17464  if (!state) return 0;
17465  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17466  if (nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, header,
17468  is_clicked = nk_true;
17469  return nk_menu_begin(ctx, win, id, is_clicked, header, size);
17470 }
17471 NK_API int
17472 nk_menu_begin_image_text(struct nk_context *ctx, const char *title, int len,
17473  nk_flags align, struct nk_image img, struct nk_vec2 size)
17474 {
17475  struct nk_window *win;
17476  struct nk_rect header;
17477  const struct nk_input *in;
17478  int is_clicked = nk_false;
17479  nk_flags state;
17480 
17481  NK_ASSERT(ctx);
17482  NK_ASSERT(ctx->current);
17483  NK_ASSERT(ctx->current->layout);
17484  if (!ctx || !ctx->current || !ctx->current->layout)
17485  return 0;
17486 
17487  win = ctx->current;
17488  state = nk_widget(&header, ctx);
17489  if (!state) return 0;
17490  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17491  if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer,
17492  header, img, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button,
17493  ctx->style.font, in))
17494  is_clicked = nk_true;
17495  return nk_menu_begin(ctx, win, title, is_clicked, header, size);
17496 }
17497 NK_API int
17499  const char *title, nk_flags align, struct nk_image img, struct nk_vec2 size)
17500 {
17501  return nk_menu_begin_image_text(ctx, title, nk_strlen(title), align, img, size);
17502 }
17503 NK_API int
17504 nk_menu_begin_symbol_text(struct nk_context *ctx, const char *title, int len,
17505  nk_flags align, enum nk_symbol_type sym, struct nk_vec2 size)
17506 {
17507  struct nk_window *win;
17508  struct nk_rect header;
17509  const struct nk_input *in;
17510  int is_clicked = nk_false;
17511  nk_flags state;
17512 
17513  NK_ASSERT(ctx);
17514  NK_ASSERT(ctx->current);
17515  NK_ASSERT(ctx->current->layout);
17516  if (!ctx || !ctx->current || !ctx->current->layout)
17517  return 0;
17518 
17519  win = ctx->current;
17520  state = nk_widget(&header, ctx);
17521  if (!state) return 0;
17522 
17523  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17524  if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer,
17525  header, sym, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button,
17526  ctx->style.font, in)) is_clicked = nk_true;
17527  return nk_menu_begin(ctx, win, title, is_clicked, header, size);
17528 }
17529 NK_API int
17531  const char *title, nk_flags align, enum nk_symbol_type sym, struct nk_vec2 size )
17532 {
17533  return nk_menu_begin_symbol_text(ctx, title, nk_strlen(title), align,sym,size);
17534 }
17535 NK_API int
17536 nk_menu_item_text(struct nk_context *ctx, const char *title, int len, nk_flags align)
17537 {
17538  return nk_contextual_item_text(ctx, title, len, align);
17539 }
17540 NK_API int
17541 nk_menu_item_label(struct nk_context *ctx, const char *label, nk_flags align)
17542 {
17543  return nk_contextual_item_label(ctx, label, align);
17544 }
17545 NK_API int
17546 nk_menu_item_image_label(struct nk_context *ctx, struct nk_image img,
17547  const char *label, nk_flags align)
17548 {
17549  return nk_contextual_item_image_label(ctx, img, label, align);
17550 }
17551 NK_API int
17552 nk_menu_item_image_text(struct nk_context *ctx, struct nk_image img,
17553  const char *text, int len, nk_flags align)
17554 {
17555  return nk_contextual_item_image_text(ctx, img, text, len, align);
17556 }
17558  const char *text, int len, nk_flags align)
17559 {
17560  return nk_contextual_item_symbol_text(ctx, sym, text, len, align);
17561 }
17563  const char *label, nk_flags align)
17564 {
17565  return nk_contextual_item_symbol_label(ctx, sym, label, align);
17566 }
17567 NK_API void nk_menu_close(struct nk_context *ctx)
17568 {
17570 }
17571 NK_API void
17572 nk_menu_end(struct nk_context *ctx)
17573 {
17575 }
17576 
17577 
17578 
17579 
17580 
17581 /* ===============================================================
17582  *
17583  * LAYOUT
17584  *
17585  * ===============================================================*/
17586 NK_API void
17587 nk_layout_set_min_row_height(struct nk_context *ctx, float height)
17588 {
17589  struct nk_window *win;
17590  struct nk_panel *layout;
17591 
17592  NK_ASSERT(ctx);
17593  NK_ASSERT(ctx->current);
17594  NK_ASSERT(ctx->current->layout);
17595  if (!ctx || !ctx->current || !ctx->current->layout)
17596  return;
17597 
17598  win = ctx->current;
17599  layout = win->layout;
17600  layout->row.min_height = height;
17601 }
17602 NK_API void
17604 {
17605  struct nk_window *win;
17606  struct nk_panel *layout;
17607 
17608  NK_ASSERT(ctx);
17609  NK_ASSERT(ctx->current);
17610  NK_ASSERT(ctx->current->layout);
17611  if (!ctx || !ctx->current || !ctx->current->layout)
17612  return;
17613 
17614  win = ctx->current;
17615  layout = win->layout;
17616  layout->row.min_height = ctx->style.font->height;
17617  layout->row.min_height += ctx->style.text.padding.y*2;
17619 }
17620 NK_LIB float
17621 nk_layout_row_calculate_usable_space(const struct nk_style *style, enum nk_panel_type type,
17622  float total_space, int columns)
17623 {
17624  float panel_padding;
17625  float panel_spacing;
17626  float panel_space;
17627 
17628  struct nk_vec2 spacing;
17629  struct nk_vec2 padding;
17630 
17631  spacing = style->window.spacing;
17632  padding = nk_panel_get_padding(style, type);
17633 
17634  /* calculate the usable panel space */
17635  panel_padding = 2 * padding.x;
17636  panel_spacing = (float)NK_MAX(columns - 1, 0) * spacing.x;
17637  panel_space = total_space - panel_padding - panel_spacing;
17638  return panel_space;
17639 }
17640 NK_LIB void
17641 nk_panel_layout(const struct nk_context *ctx, struct nk_window *win,
17642  float height, int cols)
17643 {
17644  struct nk_panel *layout;
17645  const struct nk_style *style;
17646  struct nk_command_buffer *out;
17647 
17648  struct nk_vec2 item_spacing;
17649  struct nk_color color;
17650 
17651  NK_ASSERT(ctx);
17652  NK_ASSERT(ctx->current);
17653  NK_ASSERT(ctx->current->layout);
17654  if (!ctx || !ctx->current || !ctx->current->layout)
17655  return;
17656 
17657  /* prefetch some configuration data */
17658  layout = win->layout;
17659  style = &ctx->style;
17660  out = &win->buffer;
17661  color = style->window.background;
17662  item_spacing = style->window.spacing;
17663 
17664  /* if one of these triggers you forgot to add an `if` condition around either
17665  a window, group, popup, combobox or contextual menu `begin` and `end` block.
17666  Example:
17667  if (nk_begin(...) {...} nk_end(...); or
17668  if (nk_group_begin(...) { nk_group_end(...);} */
17669  NK_ASSERT(!(layout->flags & NK_WINDOW_MINIMIZED));
17670  NK_ASSERT(!(layout->flags & NK_WINDOW_HIDDEN));
17671  NK_ASSERT(!(layout->flags & NK_WINDOW_CLOSED));
17672 
17673  /* update the current row and set the current row layout */
17674  layout->row.index = 0;
17675  layout->at_y += layout->row.height;
17676  layout->row.columns = cols;
17677  if (height == 0.0f)
17678  layout->row.height = NK_MAX(height, layout->row.min_height) + item_spacing.y;
17679  else layout->row.height = height + item_spacing.y;
17680 
17681  layout->row.item_offset = 0;
17682  if (layout->flags & NK_WINDOW_DYNAMIC) {
17683  /* draw background for dynamic panels */
17684  struct nk_rect background;
17685  background.x = win->bounds.x;
17686  background.w = win->bounds.w;
17687  background.y = layout->at_y - 1.0f;
17688  background.h = layout->row.height + 1.0f;
17689  nk_fill_rect(out, background, 0, color);
17690  }
17691 }
17692 NK_LIB void
17693 nk_row_layout(struct nk_context *ctx, enum nk_layout_format fmt,
17694  float height, int cols, int width)
17695 {
17696  /* update the current row and set the current row layout */
17697  struct nk_window *win;
17698  NK_ASSERT(ctx);
17699  NK_ASSERT(ctx->current);
17700  NK_ASSERT(ctx->current->layout);
17701  if (!ctx || !ctx->current || !ctx->current->layout)
17702  return;
17703 
17704  win = ctx->current;
17705  nk_panel_layout(ctx, win, height, cols);
17706  if (fmt == NK_DYNAMIC)
17708  else win->layout->row.type = NK_LAYOUT_STATIC_FIXED;
17709 
17710  win->layout->row.ratio = 0;
17711  win->layout->row.filled = 0;
17712  win->layout->row.item_offset = 0;
17713  win->layout->row.item_width = (float)width;
17714 }
17715 NK_API float
17716 nk_layout_ratio_from_pixel(struct nk_context *ctx, float pixel_width)
17717 {
17718  struct nk_window *win;
17719  NK_ASSERT(ctx);
17720  NK_ASSERT(pixel_width);
17721  if (!ctx || !ctx->current || !ctx->current->layout) return 0;
17722  win = ctx->current;
17723  return NK_CLAMP(0.0f, pixel_width/win->bounds.x, 1.0f);
17724 }
17725 NK_API void
17726 nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols)
17727 {
17728  nk_row_layout(ctx, NK_DYNAMIC, height, cols, 0);
17729 }
17730 NK_API void
17731 nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols)
17732 {
17733  nk_row_layout(ctx, NK_STATIC, height, cols, item_width);
17734 }
17735 NK_API void
17737  float row_height, int cols)
17738 {
17739  struct nk_window *win;
17740  struct nk_panel *layout;
17741 
17742  NK_ASSERT(ctx);
17743  NK_ASSERT(ctx->current);
17744  NK_ASSERT(ctx->current->layout);
17745  if (!ctx || !ctx->current || !ctx->current->layout)
17746  return;
17747 
17748  win = ctx->current;
17749  layout = win->layout;
17750  nk_panel_layout(ctx, win, row_height, cols);
17751  if (fmt == NK_DYNAMIC)
17752  layout->row.type = NK_LAYOUT_DYNAMIC_ROW;
17753  else layout->row.type = NK_LAYOUT_STATIC_ROW;
17754 
17755  layout->row.ratio = 0;
17756  layout->row.filled = 0;
17757  layout->row.item_width = 0;
17758  layout->row.item_offset = 0;
17759  layout->row.columns = cols;
17760 }
17761 NK_API void
17762 nk_layout_row_push(struct nk_context *ctx, float ratio_or_width)
17763 {
17764  struct nk_window *win;
17765  struct nk_panel *layout;
17766 
17767  NK_ASSERT(ctx);
17768  NK_ASSERT(ctx->current);
17769  NK_ASSERT(ctx->current->layout);
17770  if (!ctx || !ctx->current || !ctx->current->layout)
17771  return;
17772 
17773  win = ctx->current;
17774  layout = win->layout;
17775  NK_ASSERT(layout->row.type == NK_LAYOUT_STATIC_ROW || layout->row.type == NK_LAYOUT_DYNAMIC_ROW);
17776  if (layout->row.type != NK_LAYOUT_STATIC_ROW && layout->row.type != NK_LAYOUT_DYNAMIC_ROW)
17777  return;
17778 
17779  if (layout->row.type == NK_LAYOUT_DYNAMIC_ROW) {
17780  float ratio = ratio_or_width;
17781  if ((ratio + layout->row.filled) > 1.0f) return;
17782  if (ratio > 0.0f)
17783  layout->row.item_width = NK_SATURATE(ratio);
17784  else layout->row.item_width = 1.0f - layout->row.filled;
17785  } else layout->row.item_width = ratio_or_width;
17786 }
17787 NK_API void
17789 {
17790  struct nk_window *win;
17791  struct nk_panel *layout;
17792 
17793  NK_ASSERT(ctx);
17794  NK_ASSERT(ctx->current);
17795  NK_ASSERT(ctx->current->layout);
17796  if (!ctx || !ctx->current || !ctx->current->layout)
17797  return;
17798 
17799  win = ctx->current;
17800  layout = win->layout;
17801  NK_ASSERT(layout->row.type == NK_LAYOUT_STATIC_ROW || layout->row.type == NK_LAYOUT_DYNAMIC_ROW);
17802  if (layout->row.type != NK_LAYOUT_STATIC_ROW && layout->row.type != NK_LAYOUT_DYNAMIC_ROW)
17803  return;
17804  layout->row.item_width = 0;
17805  layout->row.item_offset = 0;
17806 }
17807 NK_API void
17808 nk_layout_row(struct nk_context *ctx, enum nk_layout_format fmt,
17809  float height, int cols, const float *ratio)
17810 {
17811  int i;
17812  int n_undef = 0;
17813  struct nk_window *win;
17814  struct nk_panel *layout;
17815 
17816  NK_ASSERT(ctx);
17817  NK_ASSERT(ctx->current);
17818  NK_ASSERT(ctx->current->layout);
17819  if (!ctx || !ctx->current || !ctx->current->layout)
17820  return;
17821 
17822  win = ctx->current;
17823  layout = win->layout;
17824  nk_panel_layout(ctx, win, height, cols);
17825  if (fmt == NK_DYNAMIC) {
17826  /* calculate width of undefined widget ratios */
17827  float r = 0;
17828  layout->row.ratio = ratio;
17829  for (i = 0; i < cols; ++i) {
17830  if (ratio[i] < 0.0f)
17831  n_undef++;
17832  else r += ratio[i];
17833  }
17834  r = NK_SATURATE(1.0f - r);
17835  layout->row.type = NK_LAYOUT_DYNAMIC;
17836  layout->row.item_width = (r > 0 && n_undef > 0) ? (r / (float)n_undef):0;
17837  } else {
17838  layout->row.ratio = ratio;
17839  layout->row.type = NK_LAYOUT_STATIC;
17840  layout->row.item_width = 0;
17841  layout->row.item_offset = 0;
17842  }
17843  layout->row.item_offset = 0;
17844  layout->row.filled = 0;
17845 }
17846 NK_API void
17847 nk_layout_row_template_begin(struct nk_context *ctx, float height)
17848 {
17849  struct nk_window *win;
17850  struct nk_panel *layout;
17851 
17852  NK_ASSERT(ctx);
17853  NK_ASSERT(ctx->current);
17854  NK_ASSERT(ctx->current->layout);
17855  if (!ctx || !ctx->current || !ctx->current->layout)
17856  return;
17857 
17858  win = ctx->current;
17859  layout = win->layout;
17860  nk_panel_layout(ctx, win, height, 1);
17861  layout->row.type = NK_LAYOUT_TEMPLATE;
17862  layout->row.columns = 0;
17863  layout->row.ratio = 0;
17864  layout->row.item_width = 0;
17865  layout->row.item_height = 0;
17866  layout->row.item_offset = 0;
17867  layout->row.filled = 0;
17868  layout->row.item.x = 0;
17869  layout->row.item.y = 0;
17870  layout->row.item.w = 0;
17871  layout->row.item.h = 0;
17872 }
17873 NK_API void
17875 {
17876  struct nk_window *win;
17877  struct nk_panel *layout;
17878 
17879  NK_ASSERT(ctx);
17880  NK_ASSERT(ctx->current);
17881  NK_ASSERT(ctx->current->layout);
17882  if (!ctx || !ctx->current || !ctx->current->layout)
17883  return;
17884 
17885  win = ctx->current;
17886  layout = win->layout;
17887  NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
17888  NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
17889  if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
17890  if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) return;
17891  layout->row.templates[layout->row.columns++] = -1.0f;
17892 }
17893 NK_API void
17894 nk_layout_row_template_push_variable(struct nk_context *ctx, float min_width)
17895 {
17896  struct nk_window *win;
17897  struct nk_panel *layout;
17898 
17899  NK_ASSERT(ctx);
17900  NK_ASSERT(ctx->current);
17901  NK_ASSERT(ctx->current->layout);
17902  if (!ctx || !ctx->current || !ctx->current->layout)
17903  return;
17904 
17905  win = ctx->current;
17906  layout = win->layout;
17907  NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
17908  NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
17909  if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
17910  if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) return;
17911  layout->row.templates[layout->row.columns++] = -min_width;
17912 }
17913 NK_API void
17915 {
17916  struct nk_window *win;
17917  struct nk_panel *layout;
17918 
17919  NK_ASSERT(ctx);
17920  NK_ASSERT(ctx->current);
17921  NK_ASSERT(ctx->current->layout);
17922  if (!ctx || !ctx->current || !ctx->current->layout)
17923  return;
17924 
17925  win = ctx->current;
17926  layout = win->layout;
17927  NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
17928  NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
17929  if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
17930  if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) return;
17931  layout->row.templates[layout->row.columns++] = width;
17932 }
17933 NK_API void
17935 {
17936  struct nk_window *win;
17937  struct nk_panel *layout;
17938 
17939  int i = 0;
17940  int variable_count = 0;
17941  int min_variable_count = 0;
17942  float min_fixed_width = 0.0f;
17943  float total_fixed_width = 0.0f;
17944  float max_variable_width = 0.0f;
17945 
17946  NK_ASSERT(ctx);
17947  NK_ASSERT(ctx->current);
17948  NK_ASSERT(ctx->current->layout);
17949  if (!ctx || !ctx->current || !ctx->current->layout)
17950  return;
17951 
17952  win = ctx->current;
17953  layout = win->layout;
17954  NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
17955  if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
17956  for (i = 0; i < layout->row.columns; ++i) {
17957  float width = layout->row.templates[i];
17958  if (width >= 0.0f) {
17959  total_fixed_width += width;
17960  min_fixed_width += width;
17961  } else if (width < -1.0f) {
17962  width = -width;
17963  total_fixed_width += width;
17964  max_variable_width = NK_MAX(max_variable_width, width);
17965  variable_count++;
17966  } else {
17967  min_variable_count++;
17968  variable_count++;
17969  }
17970  }
17971  if (variable_count) {
17972  float space = nk_layout_row_calculate_usable_space(&ctx->style, layout->type,
17973  layout->bounds.w, layout->row.columns);
17974  float var_width = (NK_MAX(space-min_fixed_width,0.0f)) / (float)variable_count;
17975  int enough_space = var_width >= max_variable_width;
17976  if (!enough_space)
17977  var_width = (NK_MAX(space-total_fixed_width,0)) / (float)min_variable_count;
17978  for (i = 0; i < layout->row.columns; ++i) {
17979  float *width = &layout->row.templates[i];
17980  *width = (*width >= 0.0f)? *width: (*width < -1.0f && !enough_space)? -(*width): var_width;
17981  }
17982  }
17983 }
17984 NK_API void
17986  float height, int widget_count)
17987 {
17988  struct nk_window *win;
17989  struct nk_panel *layout;
17990 
17991  NK_ASSERT(ctx);
17992  NK_ASSERT(ctx->current);
17993  NK_ASSERT(ctx->current->layout);
17994  if (!ctx || !ctx->current || !ctx->current->layout)
17995  return;
17996 
17997  win = ctx->current;
17998  layout = win->layout;
17999  nk_panel_layout(ctx, win, height, widget_count);
18000  if (fmt == NK_STATIC)
18001  layout->row.type = NK_LAYOUT_STATIC_FREE;
18002  else layout->row.type = NK_LAYOUT_DYNAMIC_FREE;
18003 
18004  layout->row.ratio = 0;
18005  layout->row.filled = 0;
18006  layout->row.item_width = 0;
18007  layout->row.item_offset = 0;
18008 }
18009 NK_API void
18011 {
18012  struct nk_window *win;
18013  struct nk_panel *layout;
18014 
18015  NK_ASSERT(ctx);
18016  NK_ASSERT(ctx->current);
18017  NK_ASSERT(ctx->current->layout);
18018  if (!ctx || !ctx->current || !ctx->current->layout)
18019  return;
18020 
18021  win = ctx->current;
18022  layout = win->layout;
18023  layout->row.item_width = 0;
18024  layout->row.item_height = 0;
18025  layout->row.item_offset = 0;
18026  nk_zero(&layout->row.item, sizeof(layout->row.item));
18027 }
18028 NK_API void
18029 nk_layout_space_push(struct nk_context *ctx, struct nk_rect rect)
18030 {
18031  struct nk_window *win;
18032  struct nk_panel *layout;
18033 
18034  NK_ASSERT(ctx);
18035  NK_ASSERT(ctx->current);
18036  NK_ASSERT(ctx->current->layout);
18037  if (!ctx || !ctx->current || !ctx->current->layout)
18038  return;
18039 
18040  win = ctx->current;
18041  layout = win->layout;
18042  layout->row.item = rect;
18043 }
18044 NK_API struct nk_rect
18046 {
18047  struct nk_rect ret;
18048  struct nk_window *win;
18049  struct nk_panel *layout;
18050 
18051  NK_ASSERT(ctx);
18052  NK_ASSERT(ctx->current);
18053  NK_ASSERT(ctx->current->layout);
18054  win = ctx->current;
18055  layout = win->layout;
18056 
18057  ret.x = layout->clip.x;
18058  ret.y = layout->clip.y;
18059  ret.w = layout->clip.w;
18060  ret.h = layout->row.height;
18061  return ret;
18062 }
18063 NK_API struct nk_rect
18065 {
18066  struct nk_rect ret;
18067  struct nk_window *win;
18068  struct nk_panel *layout;
18069 
18070  NK_ASSERT(ctx);
18071  NK_ASSERT(ctx->current);
18072  NK_ASSERT(ctx->current->layout);
18073  win = ctx->current;
18074  layout = win->layout;
18075 
18076  ret.x = layout->at_x;
18077  ret.y = layout->at_y;
18078  ret.w = layout->bounds.w - NK_MAX(layout->at_x - layout->bounds.x,0);
18079  ret.h = layout->row.height;
18080  return ret;
18081 }
18082 NK_API struct nk_vec2
18083 nk_layout_space_to_screen(struct nk_context *ctx, struct nk_vec2 ret)
18084 {
18085  struct nk_window *win;
18086  struct nk_panel *layout;
18087 
18088  NK_ASSERT(ctx);
18089  NK_ASSERT(ctx->current);
18090  NK_ASSERT(ctx->current->layout);
18091  win = ctx->current;
18092  layout = win->layout;
18093 
18094  ret.x += layout->at_x - (float)*layout->offset_x;
18095  ret.y += layout->at_y - (float)*layout->offset_y;
18096  return ret;
18097 }
18098 NK_API struct nk_vec2
18099 nk_layout_space_to_local(struct nk_context *ctx, struct nk_vec2 ret)
18100 {
18101  struct nk_window *win;
18102  struct nk_panel *layout;
18103 
18104  NK_ASSERT(ctx);
18105  NK_ASSERT(ctx->current);
18106  NK_ASSERT(ctx->current->layout);
18107  win = ctx->current;
18108  layout = win->layout;
18109 
18110  ret.x += -layout->at_x + (float)*layout->offset_x;
18111  ret.y += -layout->at_y + (float)*layout->offset_y;
18112  return ret;
18113 }
18114 NK_API struct nk_rect
18116 {
18117  struct nk_window *win;
18118  struct nk_panel *layout;
18119 
18120  NK_ASSERT(ctx);
18121  NK_ASSERT(ctx->current);
18122  NK_ASSERT(ctx->current->layout);
18123  win = ctx->current;
18124  layout = win->layout;
18125 
18126  ret.x += layout->at_x - (float)*layout->offset_x;
18127  ret.y += layout->at_y - (float)*layout->offset_y;
18128  return ret;
18129 }
18130 NK_API struct nk_rect
18132 {
18133  struct nk_window *win;
18134  struct nk_panel *layout;
18135 
18136  NK_ASSERT(ctx);
18137  NK_ASSERT(ctx->current);
18138  NK_ASSERT(ctx->current->layout);
18139  win = ctx->current;
18140  layout = win->layout;
18141 
18142  ret.x += -layout->at_x + (float)*layout->offset_x;
18143  ret.y += -layout->at_y + (float)*layout->offset_y;
18144  return ret;
18145 }
18146 NK_LIB void
18147 nk_panel_alloc_row(const struct nk_context *ctx, struct nk_window *win)
18148 {
18149  struct nk_panel *layout = win->layout;
18150  struct nk_vec2 spacing = ctx->style.window.spacing;
18151  const float row_height = layout->row.height - spacing.y;
18152  nk_panel_layout(ctx, win, row_height, layout->row.columns);
18153 }
18154 NK_LIB void
18155 nk_layout_widget_space(struct nk_rect *bounds, const struct nk_context *ctx,
18156  struct nk_window *win, int modify)
18157 {
18158  struct nk_panel *layout;
18159  const struct nk_style *style;
18160 
18161  struct nk_vec2 spacing;
18162  struct nk_vec2 padding;
18163 
18164  float item_offset = 0;
18165  float item_width = 0;
18166  float item_spacing = 0;
18167  float panel_space = 0;
18168 
18169  NK_ASSERT(ctx);
18170  NK_ASSERT(ctx->current);
18171  NK_ASSERT(ctx->current->layout);
18172  if (!ctx || !ctx->current || !ctx->current->layout)
18173  return;
18174 
18175  win = ctx->current;
18176  layout = win->layout;
18177  style = &ctx->style;
18178  NK_ASSERT(bounds);
18179 
18180  spacing = style->window.spacing;
18181  padding = nk_panel_get_padding(style, layout->type);
18182  panel_space = nk_layout_row_calculate_usable_space(&ctx->style, layout->type,
18183  layout->bounds.w, layout->row.columns);
18184 
18185  #define NK_FRAC(x) (x - (int)x) /* will be used to remove fookin gaps */
18186  /* calculate the width of one item inside the current layout space */
18187  switch (layout->row.type) {
18188  case NK_LAYOUT_DYNAMIC_FIXED: {
18189  /* scaling fixed size widgets item width */
18190  float w = NK_MAX(1.0f,panel_space) / (float)layout->row.columns;
18191  item_offset = (float)layout->row.index * w;
18192  item_width = w + NK_FRAC(item_offset);
18193  item_spacing = (float)layout->row.index * spacing.x;
18194  } break;
18195  case NK_LAYOUT_DYNAMIC_ROW: {
18196  /* scaling single ratio widget width */
18197  float w = layout->row.item_width * panel_space;
18198  item_offset = layout->row.item_offset;
18199  item_width = w + NK_FRAC(item_offset);
18200  item_spacing = 0;
18201 
18202  if (modify) {
18203  layout->row.item_offset += w + spacing.x;
18204  layout->row.filled += layout->row.item_width;
18205  layout->row.index = 0;
18206  }
18207  } break;
18208  case NK_LAYOUT_DYNAMIC_FREE: {
18209  /* panel width depended free widget placing */
18210  bounds->x = layout->at_x + (layout->bounds.w * layout->row.item.x);
18211  bounds->x -= (float)*layout->offset_x;
18212  bounds->y = layout->at_y + (layout->row.height * layout->row.item.y);
18213  bounds->y -= (float)*layout->offset_y;
18214  bounds->w = layout->bounds.w * layout->row.item.w + NK_FRAC(bounds->x);
18215  bounds->h = layout->row.height * layout->row.item.h + NK_FRAC(bounds->y);
18216  return;
18217  }
18218  case NK_LAYOUT_DYNAMIC: {
18219  /* scaling arrays of panel width ratios for every widget */
18220  float ratio, w;
18221  NK_ASSERT(layout->row.ratio);
18222  ratio = (layout->row.ratio[layout->row.index] < 0) ?
18223  layout->row.item_width : layout->row.ratio[layout->row.index];
18224 
18225  w = (ratio * panel_space);
18226  item_spacing = (float)layout->row.index * spacing.x;
18227  item_offset = layout->row.item_offset;
18228  item_width = w + NK_FRAC(item_offset);
18229 
18230  if (modify) {
18231  layout->row.item_offset += w;
18232  layout->row.filled += ratio;
18233  }
18234  } break;
18235  case NK_LAYOUT_STATIC_FIXED: {
18236  /* non-scaling fixed widgets item width */
18237  item_width = layout->row.item_width;
18238  item_offset = (float)layout->row.index * item_width;
18239  item_spacing = (float)layout->row.index * spacing.x;
18240  } break;
18241  case NK_LAYOUT_STATIC_ROW: {
18242  /* scaling single ratio widget width */
18243  item_width = layout->row.item_width;
18244  item_offset = layout->row.item_offset;
18245  item_spacing = (float)layout->row.index * spacing.x;
18246  if (modify) layout->row.item_offset += item_width;
18247  } break;
18248  case NK_LAYOUT_STATIC_FREE: {
18249  /* free widget placing */
18250  bounds->x = layout->at_x + layout->row.item.x;
18251  bounds->w = layout->row.item.w;
18252  if (((bounds->x + bounds->w) > layout->max_x) && modify)
18253  layout->max_x = (bounds->x + bounds->w);
18254  bounds->x -= (float)*layout->offset_x;
18255  bounds->y = layout->at_y + layout->row.item.y;
18256  bounds->y -= (float)*layout->offset_y;
18257  bounds->h = layout->row.item.h;
18258  return;
18259  }
18260  case NK_LAYOUT_STATIC: {
18261  /* non-scaling array of panel pixel width for every widget */
18262  item_spacing = (float)layout->row.index * spacing.x;
18263  item_width = layout->row.ratio[layout->row.index];
18264  item_offset = layout->row.item_offset;
18265  if (modify) layout->row.item_offset += item_width;
18266  } break;
18267  case NK_LAYOUT_TEMPLATE: {
18268  /* stretchy row layout with combined dynamic/static widget width*/
18269  float w;
18270  NK_ASSERT(layout->row.index < layout->row.columns);
18271  NK_ASSERT(layout->row.index < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
18272  w = layout->row.templates[layout->row.index];
18273  item_offset = layout->row.item_offset;
18274  item_width = w + NK_FRAC(item_offset);
18275  item_spacing = (float)layout->row.index * spacing.x;
18276  if (modify) layout->row.item_offset += w;
18277  } break;
18278  #undef NK_FRAC
18279  default: NK_ASSERT(0); break;
18280  };
18281 
18282  /* set the bounds of the newly allocated widget */
18283  bounds->w = item_width;
18284  bounds->h = layout->row.height - spacing.y;
18285  bounds->y = layout->at_y - (float)*layout->offset_y;
18286  bounds->x = layout->at_x + item_offset + item_spacing + padding.x;
18287  if (((bounds->x + bounds->w) > layout->max_x) && modify)
18288  layout->max_x = bounds->x + bounds->w;
18289  bounds->x -= (float)*layout->offset_x;
18290 }
18291 NK_LIB void
18292 nk_panel_alloc_space(struct nk_rect *bounds, const struct nk_context *ctx)
18293 {
18294  struct nk_window *win;
18295  struct nk_panel *layout;
18296 
18297  NK_ASSERT(ctx);
18298  NK_ASSERT(ctx->current);
18299  NK_ASSERT(ctx->current->layout);
18300  if (!ctx || !ctx->current || !ctx->current->layout)
18301  return;
18302 
18303  /* check if the end of the row has been hit and begin new row if so */
18304  win = ctx->current;
18305  layout = win->layout;
18306  if (layout->row.index >= layout->row.columns)
18307  nk_panel_alloc_row(ctx, win);
18308 
18309  /* calculate widget position and size */
18310  nk_layout_widget_space(bounds, ctx, win, nk_true);
18311  layout->row.index++;
18312 }
18313 NK_LIB void
18314 nk_layout_peek(struct nk_rect *bounds, struct nk_context *ctx)
18315 {
18316  float y;
18317  int index;
18318  struct nk_window *win;
18319  struct nk_panel *layout;
18320 
18321  NK_ASSERT(ctx);
18322  NK_ASSERT(ctx->current);
18323  NK_ASSERT(ctx->current->layout);
18324  if (!ctx || !ctx->current || !ctx->current->layout)
18325  return;
18326 
18327  win = ctx->current;
18328  layout = win->layout;
18329  y = layout->at_y;
18330  index = layout->row.index;
18331  if (layout->row.index >= layout->row.columns) {
18332  layout->at_y += layout->row.height;
18333  layout->row.index = 0;
18334  }
18335  nk_layout_widget_space(bounds, ctx, win, nk_false);
18336  if (!layout->row.index) {
18337  bounds->x -= layout->row.item_offset;
18338  }
18339  layout->at_y = y;
18340  layout->row.index = index;
18341 }
18342 
18343 
18344 
18345 
18346 
18347 /* ===============================================================
18348  *
18349  * TREE
18350  *
18351  * ===============================================================*/
18352 NK_INTERN int
18353 nk_tree_state_base(struct nk_context *ctx, enum nk_tree_type type,
18354  struct nk_image *img, const char *title, enum nk_collapse_states *state)
18355 {
18356  struct nk_window *win;
18357  struct nk_panel *layout;
18358  const struct nk_style *style;
18359  struct nk_command_buffer *out;
18360  const struct nk_input *in;
18361  const struct nk_style_button *button;
18362  enum nk_symbol_type symbol;
18363  float row_height;
18364 
18365  struct nk_vec2 item_spacing;
18366  struct nk_rect header = {0,0,0,0};
18367  struct nk_rect sym = {0,0,0,0};
18368  struct nk_text text;
18369 
18370  nk_flags ws = 0;
18371  enum nk_widget_layout_states widget_state;
18372 
18373  NK_ASSERT(ctx);
18374  NK_ASSERT(ctx->current);
18375  NK_ASSERT(ctx->current->layout);
18376  if (!ctx || !ctx->current || !ctx->current->layout)
18377  return 0;
18378 
18379  /* cache some data */
18380  win = ctx->current;
18381  layout = win->layout;
18382  out = &win->buffer;
18383  style = &ctx->style;
18384  item_spacing = style->window.spacing;
18385 
18386  /* calculate header bounds and draw background */
18387  row_height = style->font->height + 2 * style->tab.padding.y;
18388  nk_layout_set_min_row_height(ctx, row_height);
18389  nk_layout_row_dynamic(ctx, row_height, 1);
18391 
18392  widget_state = nk_widget(&header, ctx);
18393  if (type == NK_TREE_TAB) {
18394  const struct nk_style_item *background = &style->tab.background;
18395  if (background->type == NK_STYLE_ITEM_IMAGE) {
18396  nk_draw_image(out, header, &background->data.image, nk_white);
18397  text.background = nk_rgba(0,0,0,0);
18398  } else {
18399  text.background = background->data.color;
18400  nk_fill_rect(out, header, 0, style->tab.border_color);
18401  nk_fill_rect(out, nk_shrink_rect(header, style->tab.border),
18402  style->tab.rounding, background->data.color);
18403  }
18404  } else text.background = style->window.background;
18405 
18406  /* update node state */
18407  in = (!(layout->flags & NK_WINDOW_ROM)) ? &ctx->input: 0;
18408  in = (in && widget_state == NK_WIDGET_VALID) ? &ctx->input : 0;
18409  if (nk_button_behavior(&ws, header, in, NK_BUTTON_DEFAULT))
18410  *state = (*state == NK_MAXIMIZED) ? NK_MINIMIZED : NK_MAXIMIZED;
18411 
18412  /* select correct button style */
18413  if (*state == NK_MAXIMIZED) {
18414  symbol = style->tab.sym_maximize;
18415  if (type == NK_TREE_TAB)
18416  button = &style->tab.tab_maximize_button;
18417  else button = &style->tab.node_maximize_button;
18418  } else {
18419  symbol = style->tab.sym_minimize;
18420  if (type == NK_TREE_TAB)
18421  button = &style->tab.tab_minimize_button;
18422  else button = &style->tab.node_minimize_button;
18423  }
18424 
18425  {/* draw triangle button */
18426  sym.w = sym.h = style->font->height;
18427  sym.y = header.y + style->tab.padding.y;
18428  sym.x = header.x + style->tab.padding.x;
18429  nk_do_button_symbol(&ws, &win->buffer, sym, symbol, NK_BUTTON_DEFAULT,
18430  button, 0, style->font);
18431 
18432  if (img) {
18433  /* draw optional image icon */
18434  sym.x = sym.x + sym.w + 4 * item_spacing.x;
18435  nk_draw_image(&win->buffer, sym, img, nk_white);
18436  sym.w = style->font->height + style->tab.spacing.x;}
18437  }
18438 
18439  {/* draw label */
18440  struct nk_rect label;
18441  header.w = NK_MAX(header.w, sym.w + item_spacing.x);
18442  label.x = sym.x + sym.w + item_spacing.x;
18443  label.y = sym.y;
18444  label.w = header.w - (sym.w + item_spacing.y + style->tab.indent);
18445  label.h = style->font->height;
18446  text.text = style->tab.text;
18447  text.padding = nk_vec2(0,0);
18448  nk_widget_text(out, label, title, nk_strlen(title), &text,
18449  NK_TEXT_LEFT, style->font);}
18450 
18451  /* increase x-axis cursor widget position pointer */
18452  if (*state == NK_MAXIMIZED) {
18453  layout->at_x = header.x + (float)*layout->offset_x + style->tab.indent;
18454  layout->bounds.w = NK_MAX(layout->bounds.w, style->tab.indent);
18455  layout->bounds.w -= (style->tab.indent + style->window.padding.x);
18456  layout->row.tree_depth++;
18457  return nk_true;
18458  } else return nk_false;
18459 }
18460 NK_INTERN int
18461 nk_tree_base(struct nk_context *ctx, enum nk_tree_type type,
18462  struct nk_image *img, const char *title, enum nk_collapse_states initial_state,
18463  const char *hash, int len, int line)
18464 {
18465  struct nk_window *win = ctx->current;
18466  int title_len = 0;
18467  nk_hash tree_hash = 0;
18468  nk_uint *state = 0;
18469 
18470  /* retrieve tree state from internal widget state tables */
18471  if (!hash) {
18472  title_len = (int)nk_strlen(title);
18473  tree_hash = nk_murmur_hash(title, (int)title_len, (nk_hash)line);
18474  } else tree_hash = nk_murmur_hash(hash, len, (nk_hash)line);
18475  state = nk_find_value(win, tree_hash);
18476  if (!state) {
18477  state = nk_add_value(ctx, win, tree_hash, 0);
18478  *state = initial_state;
18479  }
18480  return nk_tree_state_base(ctx, type, img, title, (enum nk_collapse_states*)state);
18481 }
18482 NK_API int
18483 nk_tree_state_push(struct nk_context *ctx, enum nk_tree_type type,
18484  const char *title, enum nk_collapse_states *state)
18485 {
18486  return nk_tree_state_base(ctx, type, 0, title, state);
18487 }
18488 NK_API int
18490  struct nk_image img, const char *title, enum nk_collapse_states *state)
18491 {
18492  return nk_tree_state_base(ctx, type, &img, title, state);
18493 }
18494 NK_API void
18496 {
18497  struct nk_window *win = 0;
18498  struct nk_panel *layout = 0;
18499 
18500  NK_ASSERT(ctx);
18501  NK_ASSERT(ctx->current);
18502  NK_ASSERT(ctx->current->layout);
18503  if (!ctx || !ctx->current || !ctx->current->layout)
18504  return;
18505 
18506  win = ctx->current;
18507  layout = win->layout;
18508  layout->at_x -= ctx->style.tab.indent + ctx->style.window.padding.x;
18509  layout->bounds.w += ctx->style.tab.indent + ctx->style.window.padding.x;
18510  NK_ASSERT(layout->row.tree_depth);
18511  layout->row.tree_depth--;
18512 }
18513 NK_API int
18515  const char *title, enum nk_collapse_states initial_state,
18516  const char *hash, int len, int line)
18517 {
18518  return nk_tree_base(ctx, type, 0, title, initial_state, hash, len, line);
18519 }
18520 NK_API int
18522  struct nk_image img, const char *title, enum nk_collapse_states initial_state,
18523  const char *hash, int len,int seed)
18524 {
18525  return nk_tree_base(ctx, type, &img, title, initial_state, hash, len, seed);
18526 }
18527 NK_API void
18528 nk_tree_pop(struct nk_context *ctx)
18529 {
18531 }
18532 NK_INTERN int
18533 nk_tree_element_image_push_hashed_base(struct nk_context *ctx, enum nk_tree_type type,
18534  struct nk_image *img, const char *title, int title_len,
18535  enum nk_collapse_states *state, int *selected)
18536 {
18537  struct nk_window *win;
18538  struct nk_panel *layout;
18539  const struct nk_style *style;
18540  struct nk_command_buffer *out;
18541  const struct nk_input *in;
18542  const struct nk_style_button *button;
18543  enum nk_symbol_type symbol;
18544  float row_height;
18545  struct nk_vec2 padding;
18546 
18547  int text_len;
18548  float text_width;
18549 
18550  struct nk_vec2 item_spacing;
18551  struct nk_rect header = {0,0,0,0};
18552  struct nk_rect sym = {0,0,0,0};
18553  struct nk_text text;
18554 
18555  nk_flags ws = 0;
18556  enum nk_widget_layout_states widget_state;
18557 
18558  NK_ASSERT(ctx);
18559  NK_ASSERT(ctx->current);
18560  NK_ASSERT(ctx->current->layout);
18561  if (!ctx || !ctx->current || !ctx->current->layout)
18562  return 0;
18563 
18564  /* cache some data */
18565  win = ctx->current;
18566  layout = win->layout;
18567  out = &win->buffer;
18568  style = &ctx->style;
18569  item_spacing = style->window.spacing;
18570  padding = style->selectable.padding;
18571 
18572  /* calculate header bounds and draw background */
18573  row_height = style->font->height + 2 * style->tab.padding.y;
18574  nk_layout_set_min_row_height(ctx, row_height);
18575  nk_layout_row_dynamic(ctx, row_height, 1);
18577 
18578  widget_state = nk_widget(&header, ctx);
18579  if (type == NK_TREE_TAB) {
18580  const struct nk_style_item *background = &style->tab.background;
18581  if (background->type == NK_STYLE_ITEM_IMAGE) {
18582  nk_draw_image(out, header, &background->data.image, nk_white);
18583  text.background = nk_rgba(0,0,0,0);
18584  } else {
18585  text.background = background->data.color;
18586  nk_fill_rect(out, header, 0, style->tab.border_color);
18587  nk_fill_rect(out, nk_shrink_rect(header, style->tab.border),
18588  style->tab.rounding, background->data.color);
18589  }
18590  } else text.background = style->window.background;
18591 
18592  in = (!(layout->flags & NK_WINDOW_ROM)) ? &ctx->input: 0;
18593  in = (in && widget_state == NK_WIDGET_VALID) ? &ctx->input : 0;
18594 
18595  /* select correct button style */
18596  if (*state == NK_MAXIMIZED) {
18597  symbol = style->tab.sym_maximize;
18598  if (type == NK_TREE_TAB)
18599  button = &style->tab.tab_maximize_button;
18600  else button = &style->tab.node_maximize_button;
18601  } else {
18602  symbol = style->tab.sym_minimize;
18603  if (type == NK_TREE_TAB)
18604  button = &style->tab.tab_minimize_button;
18605  else button = &style->tab.node_minimize_button;
18606  }
18607  {/* draw triangle button */
18608  sym.w = sym.h = style->font->height;
18609  sym.y = header.y + style->tab.padding.y;
18610  sym.x = header.x + style->tab.padding.x;
18611  if (nk_do_button_symbol(&ws, &win->buffer, sym, symbol, NK_BUTTON_DEFAULT, button, in, style->font))
18612  *state = (*state == NK_MAXIMIZED) ? NK_MINIMIZED : NK_MAXIMIZED;}
18613 
18614  /* draw label */
18615  {nk_flags dummy = 0;
18616  struct nk_rect label;
18617  /* calculate size of the text and tooltip */
18618  text_len = nk_strlen(title);
18619  text_width = style->font->width(style->font->userdata, style->font->height, title, text_len);
18620  text_width += (4 * padding.x);
18621 
18622  header.w = NK_MAX(header.w, sym.w + item_spacing.x);
18623  label.x = sym.x + sym.w + item_spacing.x;
18624  label.y = sym.y;
18625  label.w = NK_MIN(header.w - (sym.w + item_spacing.y + style->tab.indent), text_width);
18626  label.h = style->font->height;
18627 
18628  if (img) {
18629  nk_do_selectable_image(&dummy, &win->buffer, label, title, title_len, NK_TEXT_LEFT,
18630  selected, img, &style->selectable, in, style->font);
18631  } else nk_do_selectable(&dummy, &win->buffer, label, title, title_len, NK_TEXT_LEFT,
18632  selected, &style->selectable, in, style->font);
18633  }
18634  /* increase x-axis cursor widget position pointer */
18635  if (*state == NK_MAXIMIZED) {
18636  layout->at_x = header.x + (float)*layout->offset_x + style->tab.indent;
18637  layout->bounds.w = NK_MAX(layout->bounds.w, style->tab.indent);
18638  layout->bounds.w -= (style->tab.indent + style->window.padding.x);
18639  layout->row.tree_depth++;
18640  return nk_true;
18641  } else return nk_false;
18642 }
18643 NK_INTERN int
18644 nk_tree_element_base(struct nk_context *ctx, enum nk_tree_type type,
18645  struct nk_image *img, const char *title, enum nk_collapse_states initial_state,
18646  int *selected, const char *hash, int len, int line)
18647 {
18648  struct nk_window *win = ctx->current;
18649  int title_len = 0;
18650  nk_hash tree_hash = 0;
18651  nk_uint *state = 0;
18652 
18653  /* retrieve tree state from internal widget state tables */
18654  if (!hash) {
18655  title_len = (int)nk_strlen(title);
18656  tree_hash = nk_murmur_hash(title, (int)title_len, (nk_hash)line);
18657  } else tree_hash = nk_murmur_hash(hash, len, (nk_hash)line);
18658  state = nk_find_value(win, tree_hash);
18659  if (!state) {
18660  state = nk_add_value(ctx, win, tree_hash, 0);
18661  *state = initial_state;
18662  } return nk_tree_element_image_push_hashed_base(ctx, type, img, title,
18663  nk_strlen(title), (enum nk_collapse_states*)state, selected);
18664 }
18665 NK_API int
18667  const char *title, enum nk_collapse_states initial_state,
18668  int *selected, const char *hash, int len, int seed)
18669 {
18670  return nk_tree_element_base(ctx, type, 0, title, initial_state, selected, hash, len, seed);
18671 }
18672 NK_API int
18674  struct nk_image img, const char *title, enum nk_collapse_states initial_state,
18675  int *selected, const char *hash, int len,int seed)
18676 {
18677  return nk_tree_element_base(ctx, type, &img, title, initial_state, selected, hash, len, seed);
18678 }
18679 NK_API void
18681 {
18683 }
18684 
18685 
18686 
18687 
18688 
18689 /* ===============================================================
18690  *
18691  * GROUP
18692  *
18693  * ===============================================================*/
18694 NK_API int
18696  nk_uint *x_offset, nk_uint *y_offset, const char *title, nk_flags flags)
18697 {
18698  struct nk_rect bounds;
18699  struct nk_window panel;
18700  struct nk_window *win;
18701 
18702  win = ctx->current;
18703  nk_panel_alloc_space(&bounds, ctx);
18704  {const struct nk_rect *c = &win->layout->clip;
18705  if (!NK_INTERSECT(c->x, c->y, c->w, c->h, bounds.x, bounds.y, bounds.w, bounds.h) &&
18706  !(flags & NK_WINDOW_MOVABLE)) {
18707  return 0;
18708  }}
18709  if (win->flags & NK_WINDOW_ROM)
18710  flags |= NK_WINDOW_ROM;
18711 
18712  /* initialize a fake window to create the panel from */
18713  nk_zero(&panel, sizeof(panel));
18714  panel.bounds = bounds;
18715  panel.flags = flags;
18716  panel.scrollbar.x = *x_offset;
18717  panel.scrollbar.y = *y_offset;
18718  panel.buffer = win->buffer;
18719  panel.layout = (struct nk_panel*)nk_create_panel(ctx);
18720  ctx->current = &panel;
18721  nk_panel_begin(ctx, (flags & NK_WINDOW_TITLE) ? title: 0, NK_PANEL_GROUP);
18722 
18723  win->buffer = panel.buffer;
18724  win->buffer.clip = panel.layout->clip;
18725  panel.layout->offset_x = x_offset;
18726  panel.layout->offset_y = y_offset;
18727  panel.layout->parent = win->layout;
18728  win->layout = panel.layout;
18729 
18730  ctx->current = win;
18731  if ((panel.layout->flags & NK_WINDOW_CLOSED) ||
18732  (panel.layout->flags & NK_WINDOW_MINIMIZED))
18733  {
18734  nk_flags f = panel.layout->flags;
18736  if (f & NK_WINDOW_CLOSED)
18737  return NK_WINDOW_CLOSED;
18738  if (f & NK_WINDOW_MINIMIZED)
18739  return NK_WINDOW_MINIMIZED;
18740  }
18741  return 1;
18742 }
18743 NK_API void
18745 {
18746  struct nk_window *win;
18747  struct nk_panel *parent;
18748  struct nk_panel *g;
18749 
18750  struct nk_rect clip;
18751  struct nk_window pan;
18752  struct nk_vec2 panel_padding;
18753 
18754  NK_ASSERT(ctx);
18755  NK_ASSERT(ctx->current);
18756  if (!ctx || !ctx->current)
18757  return;
18758 
18759  /* make sure nk_group_begin was called correctly */
18760  NK_ASSERT(ctx->current);
18761  win = ctx->current;
18762  NK_ASSERT(win->layout);
18763  g = win->layout;
18764  NK_ASSERT(g->parent);
18765  parent = g->parent;
18766 
18767  /* dummy window */
18768  nk_zero_struct(pan);
18769  panel_padding = nk_panel_get_padding(&ctx->style, NK_PANEL_GROUP);
18770  pan.bounds.y = g->bounds.y - (g->header_height + g->menu.h);
18771  pan.bounds.x = g->bounds.x - panel_padding.x;
18772  pan.bounds.w = g->bounds.w + 2 * panel_padding.x;
18773  pan.bounds.h = g->bounds.h + g->header_height + g->menu.h;
18774  if (g->flags & NK_WINDOW_BORDER) {
18775  pan.bounds.x -= g->border;
18776  pan.bounds.y -= g->border;
18777  pan.bounds.w += 2*g->border;
18778  pan.bounds.h += 2*g->border;
18779  }
18780  if (!(g->flags & NK_WINDOW_NO_SCROLLBAR)) {
18781  pan.bounds.w += ctx->style.window.scrollbar_size.x;
18782  pan.bounds.h += ctx->style.window.scrollbar_size.y;
18783  }
18784  pan.scrollbar.x = *g->offset_x;
18785  pan.scrollbar.y = *g->offset_y;
18786  pan.flags = g->flags;
18787  pan.buffer = win->buffer;
18788  pan.layout = g;
18789  pan.parent = win;
18790  ctx->current = &pan;
18791 
18792  /* make sure group has correct clipping rectangle */
18793  nk_unify(&clip, &parent->clip, pan.bounds.x, pan.bounds.y,
18794  pan.bounds.x + pan.bounds.w, pan.bounds.y + pan.bounds.h + panel_padding.x);
18795  nk_push_scissor(&pan.buffer, clip);
18796  nk_end(ctx);
18797 
18798  win->buffer = pan.buffer;
18799  nk_push_scissor(&win->buffer, parent->clip);
18800  ctx->current = win;
18801  win->layout = parent;
18802  g->bounds = pan.bounds;
18803  return;
18804 }
18805 NK_API int
18807  struct nk_scroll *scroll, const char *title, nk_flags flags)
18808 {
18809  return nk_group_scrolled_offset_begin(ctx, &scroll->x, &scroll->y, title, flags);
18810 }
18811 NK_API int
18812 nk_group_begin_titled(struct nk_context *ctx, const char *id,
18813  const char *title, nk_flags flags)
18814 {
18815  int id_len;
18816  nk_hash id_hash;
18817  struct nk_window *win;
18818  nk_uint *x_offset;
18819  nk_uint *y_offset;
18820 
18821  NK_ASSERT(ctx);
18822  NK_ASSERT(id);
18823  NK_ASSERT(ctx->current);
18824  NK_ASSERT(ctx->current->layout);
18825  if (!ctx || !ctx->current || !ctx->current->layout || !id)
18826  return 0;
18827 
18828  /* find persistent group scrollbar value */
18829  win = ctx->current;
18830  id_len = (int)nk_strlen(id);
18831  id_hash = nk_murmur_hash(id, (int)id_len, NK_PANEL_GROUP);
18832  x_offset = nk_find_value(win, id_hash);
18833  if (!x_offset) {
18834  x_offset = nk_add_value(ctx, win, id_hash, 0);
18835  y_offset = nk_add_value(ctx, win, id_hash+1, 0);
18836 
18837  NK_ASSERT(x_offset);
18838  NK_ASSERT(y_offset);
18839  if (!x_offset || !y_offset) return 0;
18840  *x_offset = *y_offset = 0;
18841  } else y_offset = nk_find_value(win, id_hash+1);
18842  return nk_group_scrolled_offset_begin(ctx, x_offset, y_offset, title, flags);
18843 }
18844 NK_API int
18845 nk_group_begin(struct nk_context *ctx, const char *title, nk_flags flags)
18846 {
18847  return nk_group_begin_titled(ctx, title, title, flags);
18848 }
18849 NK_API void
18850 nk_group_end(struct nk_context *ctx)
18851 {
18853 }
18854 NK_API void
18855 nk_group_get_scroll(struct nk_context *ctx, const char *id, nk_uint *x_offset, nk_uint *y_offset)
18856 {
18857  int id_len;
18858  nk_hash id_hash;
18859  struct nk_window *win;
18860  nk_uint *x_offset_ptr;
18861  nk_uint *y_offset_ptr;
18862 
18863  NK_ASSERT(ctx);
18864  NK_ASSERT(id);
18865  NK_ASSERT(ctx->current);
18866  NK_ASSERT(ctx->current->layout);
18867  if (!ctx || !ctx->current || !ctx->current->layout || !id)
18868  return;
18869 
18870  /* find persistent group scrollbar value */
18871  win = ctx->current;
18872  id_len = (int)nk_strlen(id);
18873  id_hash = nk_murmur_hash(id, (int)id_len, NK_PANEL_GROUP);
18874  x_offset_ptr = nk_find_value(win, id_hash);
18875  if (!x_offset_ptr) {
18876  x_offset_ptr = nk_add_value(ctx, win, id_hash, 0);
18877  y_offset_ptr = nk_add_value(ctx, win, id_hash+1, 0);
18878 
18879  NK_ASSERT(x_offset_ptr);
18880  NK_ASSERT(y_offset_ptr);
18881  if (!x_offset_ptr || !y_offset_ptr) return;
18882  *x_offset_ptr = *y_offset_ptr = 0;
18883  } else y_offset_ptr = nk_find_value(win, id_hash+1);
18884  if (x_offset)
18885  *x_offset = *x_offset_ptr;
18886  if (y_offset)
18887  *y_offset = *y_offset_ptr;
18888 }
18889 NK_API void
18890 nk_group_set_scroll(struct nk_context *ctx, const char *id, nk_uint x_offset, nk_uint y_offset)
18891 {
18892  int id_len;
18893  nk_hash id_hash;
18894  struct nk_window *win;
18895  nk_uint *x_offset_ptr;
18896  nk_uint *y_offset_ptr;
18897 
18898  NK_ASSERT(ctx);
18899  NK_ASSERT(id);
18900  NK_ASSERT(ctx->current);
18901  NK_ASSERT(ctx->current->layout);
18902  if (!ctx || !ctx->current || !ctx->current->layout || !id)
18903  return;
18904 
18905  /* find persistent group scrollbar value */
18906  win = ctx->current;
18907  id_len = (int)nk_strlen(id);
18908  id_hash = nk_murmur_hash(id, (int)id_len, NK_PANEL_GROUP);
18909  x_offset_ptr = nk_find_value(win, id_hash);
18910  if (!x_offset_ptr) {
18911  x_offset_ptr = nk_add_value(ctx, win, id_hash, 0);
18912  y_offset_ptr = nk_add_value(ctx, win, id_hash+1, 0);
18913 
18914  NK_ASSERT(x_offset_ptr);
18915  NK_ASSERT(y_offset_ptr);
18916  if (!x_offset_ptr || !y_offset_ptr) return;
18917  *x_offset_ptr = *y_offset_ptr = 0;
18918  } else y_offset_ptr = nk_find_value(win, id_hash+1);
18919  *x_offset_ptr = x_offset;
18920  *y_offset_ptr = y_offset;
18921 }
18922 
18923 
18924 
18925 
18926 /* ===============================================================
18927  *
18928  * LIST VIEW
18929  *
18930  * ===============================================================*/
18931 NK_API int
18932 nk_list_view_begin(struct nk_context *ctx, struct nk_list_view *view,
18933  const char *title, nk_flags flags, int row_height, int row_count)
18934 {
18935  int title_len;
18936  nk_hash title_hash;
18937  nk_uint *x_offset;
18938  nk_uint *y_offset;
18939 
18940  int result;
18941  struct nk_window *win;
18942  struct nk_panel *layout;
18943  const struct nk_style *style;
18944  struct nk_vec2 item_spacing;
18945 
18946  NK_ASSERT(ctx);
18947  NK_ASSERT(view);
18948  NK_ASSERT(title);
18949  if (!ctx || !view || !title) return 0;
18950 
18951  win = ctx->current;
18952  style = &ctx->style;
18953  item_spacing = style->window.spacing;
18954  row_height += NK_MAX(0, (int)item_spacing.y);
18955 
18956  /* find persistent list view scrollbar offset */
18957  title_len = (int)nk_strlen(title);
18958  title_hash = nk_murmur_hash(title, (int)title_len, NK_PANEL_GROUP);
18959  x_offset = nk_find_value(win, title_hash);
18960  if (!x_offset) {
18961  x_offset = nk_add_value(ctx, win, title_hash, 0);
18962  y_offset = nk_add_value(ctx, win, title_hash+1, 0);
18963 
18964  NK_ASSERT(x_offset);
18965  NK_ASSERT(y_offset);
18966  if (!x_offset || !y_offset) return 0;
18967  *x_offset = *y_offset = 0;
18968  } else y_offset = nk_find_value(win, title_hash+1);
18969  view->scroll_value = *y_offset;
18970  view->scroll_pointer = y_offset;
18971 
18972  *y_offset = 0;
18973  result = nk_group_scrolled_offset_begin(ctx, x_offset, y_offset, title, flags);
18974  win = ctx->current;
18975  layout = win->layout;
18976 
18977  view->total_height = row_height * NK_MAX(row_count,1);
18978  view->begin = (int)NK_MAX(((float)view->scroll_value / (float)row_height), 0.0f);
18979  view->count = (int)NK_MAX(nk_iceilf((layout->clip.h)/(float)row_height),0);
18980  view->count = NK_MIN(view->count, row_count - view->begin);
18981  view->end = view->begin + view->count;
18982  view->ctx = ctx;
18983  return result;
18984 }
18985 NK_API void
18986 nk_list_view_end(struct nk_list_view *view)
18987 {
18988  struct nk_context *ctx;
18989  struct nk_window *win;
18990  struct nk_panel *layout;
18991 
18992  NK_ASSERT(view);
18993  NK_ASSERT(view->ctx);
18994  NK_ASSERT(view->scroll_pointer);
18995  if (!view || !view->ctx) return;
18996 
18997  ctx = view->ctx;
18998  win = ctx->current;
18999  layout = win->layout;
19000  layout->at_y = layout->bounds.y + (float)view->total_height;
19001  *view->scroll_pointer = *view->scroll_pointer + view->scroll_value;
19002  nk_group_end(view->ctx);
19003 }
19004 
19005 
19006 
19007 
19008 
19009 /* ===============================================================
19010  *
19011  * WIDGET
19012  *
19013  * ===============================================================*/
19014 NK_API struct nk_rect
19016 {
19017  struct nk_rect bounds;
19018  NK_ASSERT(ctx);
19019  NK_ASSERT(ctx->current);
19020  if (!ctx || !ctx->current)
19021  return nk_rect(0,0,0,0);
19022  nk_layout_peek(&bounds, ctx);
19023  return bounds;
19024 }
19025 NK_API struct nk_vec2
19027 {
19028  struct nk_rect bounds;
19029  NK_ASSERT(ctx);
19030  NK_ASSERT(ctx->current);
19031  if (!ctx || !ctx->current)
19032  return nk_vec2(0,0);
19033 
19034  nk_layout_peek(&bounds, ctx);
19035  return nk_vec2(bounds.x, bounds.y);
19036 }
19037 NK_API struct nk_vec2
19038 nk_widget_size(struct nk_context *ctx)
19039 {
19040  struct nk_rect bounds;
19041  NK_ASSERT(ctx);
19042  NK_ASSERT(ctx->current);
19043  if (!ctx || !ctx->current)
19044  return nk_vec2(0,0);
19045 
19046  nk_layout_peek(&bounds, ctx);
19047  return nk_vec2(bounds.w, bounds.h);
19048 }
19049 NK_API float
19051 {
19052  struct nk_rect bounds;
19053  NK_ASSERT(ctx);
19054  NK_ASSERT(ctx->current);
19055  if (!ctx || !ctx->current)
19056  return 0;
19057 
19058  nk_layout_peek(&bounds, ctx);
19059  return bounds.w;
19060 }
19061 NK_API float
19063 {
19064  struct nk_rect bounds;
19065  NK_ASSERT(ctx);
19066  NK_ASSERT(ctx->current);
19067  if (!ctx || !ctx->current)
19068  return 0;
19069 
19070  nk_layout_peek(&bounds, ctx);
19071  return bounds.h;
19072 }
19073 NK_API int
19075 {
19076  struct nk_rect c, v;
19077  struct nk_rect bounds;
19078  NK_ASSERT(ctx);
19079  NK_ASSERT(ctx->current);
19080  if (!ctx || !ctx->current || ctx->active != ctx->current)
19081  return 0;
19082 
19083  c = ctx->current->layout->clip;
19084  c.x = (float)((int)c.x);
19085  c.y = (float)((int)c.y);
19086  c.w = (float)((int)c.w);
19087  c.h = (float)((int)c.h);
19088 
19089  nk_layout_peek(&bounds, ctx);
19090  nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
19091  if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
19092  return 0;
19093  return nk_input_is_mouse_hovering_rect(&ctx->input, bounds);
19094 }
19095 NK_API int
19097 {
19098  struct nk_rect c, v;
19099  struct nk_rect bounds;
19100  NK_ASSERT(ctx);
19101  NK_ASSERT(ctx->current);
19102  if (!ctx || !ctx->current || ctx->active != ctx->current)
19103  return 0;
19104 
19105  c = ctx->current->layout->clip;
19106  c.x = (float)((int)c.x);
19107  c.y = (float)((int)c.y);
19108  c.w = (float)((int)c.w);
19109  c.h = (float)((int)c.h);
19110 
19111  nk_layout_peek(&bounds, ctx);
19112  nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
19113  if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
19114  return 0;
19115  return nk_input_mouse_clicked(&ctx->input, btn, bounds);
19116 }
19117 NK_API int
19118 nk_widget_has_mouse_click_down(struct nk_context *ctx, enum nk_buttons btn, int down)
19119 {
19120  struct nk_rect c, v;
19121  struct nk_rect bounds;
19122  NK_ASSERT(ctx);
19123  NK_ASSERT(ctx->current);
19124  if (!ctx || !ctx->current || ctx->active != ctx->current)
19125  return 0;
19126 
19127  c = ctx->current->layout->clip;
19128  c.x = (float)((int)c.x);
19129  c.y = (float)((int)c.y);
19130  c.w = (float)((int)c.w);
19131  c.h = (float)((int)c.h);
19132 
19133  nk_layout_peek(&bounds, ctx);
19134  nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
19135  if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
19136  return 0;
19137  return nk_input_has_mouse_click_down_in_rect(&ctx->input, btn, bounds, down);
19138 }
19140 nk_widget(struct nk_rect *bounds, const struct nk_context *ctx)
19141 {
19142  struct nk_rect c, v;
19143  struct nk_window *win;
19144  struct nk_panel *layout;
19145  const struct nk_input *in;
19146 
19147  NK_ASSERT(ctx);
19148  NK_ASSERT(ctx->current);
19149  NK_ASSERT(ctx->current->layout);
19150  if (!ctx || !ctx->current || !ctx->current->layout)
19151  return NK_WIDGET_INVALID;
19152 
19153  /* allocate space and check if the widget needs to be updated and drawn */
19154  nk_panel_alloc_space(bounds, ctx);
19155  win = ctx->current;
19156  layout = win->layout;
19157  in = &ctx->input;
19158  c = layout->clip;
19159 
19160  /* if one of these triggers you forgot to add an `if` condition around either
19161  a window, group, popup, combobox or contextual menu `begin` and `end` block.
19162  Example:
19163  if (nk_begin(...) {...} nk_end(...); or
19164  if (nk_group_begin(...) { nk_group_end(...);} */
19165  NK_ASSERT(!(layout->flags & NK_WINDOW_MINIMIZED));
19166  NK_ASSERT(!(layout->flags & NK_WINDOW_HIDDEN));
19167  NK_ASSERT(!(layout->flags & NK_WINDOW_CLOSED));
19168 
19169  /* need to convert to int here to remove floating point errors */
19170  bounds->x = (float)((int)bounds->x);
19171  bounds->y = (float)((int)bounds->y);
19172  bounds->w = (float)((int)bounds->w);
19173  bounds->h = (float)((int)bounds->h);
19174 
19175  c.x = (float)((int)c.x);
19176  c.y = (float)((int)c.y);
19177  c.w = (float)((int)c.w);
19178  c.h = (float)((int)c.h);
19179 
19180  nk_unify(&v, &c, bounds->x, bounds->y, bounds->x + bounds->w, bounds->y + bounds->h);
19181  if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds->x, bounds->y, bounds->w, bounds->h))
19182  return NK_WIDGET_INVALID;
19183  if (!NK_INBOX(in->mouse.pos.x, in->mouse.pos.y, v.x, v.y, v.w, v.h))
19184  return NK_WIDGET_ROM;
19185  return NK_WIDGET_VALID;
19186 }
19188 nk_widget_fitting(struct nk_rect *bounds, struct nk_context *ctx,
19189  struct nk_vec2 item_padding)
19190 {
19191  /* update the bounds to stand without padding */
19192  struct nk_window *win;
19193  struct nk_style *style;
19194  struct nk_panel *layout;
19195  enum nk_widget_layout_states state;
19196  struct nk_vec2 panel_padding;
19197 
19198  NK_ASSERT(ctx);
19199  NK_ASSERT(ctx->current);
19200  NK_ASSERT(ctx->current->layout);
19201  if (!ctx || !ctx->current || !ctx->current->layout)
19202  return NK_WIDGET_INVALID;
19203 
19204  win = ctx->current;
19205  style = &ctx->style;
19206  layout = win->layout;
19207  state = nk_widget(bounds, ctx);
19208 
19209  panel_padding = nk_panel_get_padding(style, layout->type);
19210  if (layout->row.index == 1) {
19211  bounds->w += panel_padding.x;
19212  bounds->x -= panel_padding.x;
19213  } else bounds->x -= item_padding.x;
19214 
19215  if (layout->row.index == layout->row.columns)
19216  bounds->w += panel_padding.x;
19217  else bounds->w += item_padding.x;
19218  return state;
19219 }
19220 NK_API void
19221 nk_spacing(struct nk_context *ctx, int cols)
19222 {
19223  struct nk_window *win;
19224  struct nk_panel *layout;
19225  struct nk_rect none;
19226  int i, index, rows;
19227 
19228  NK_ASSERT(ctx);
19229  NK_ASSERT(ctx->current);
19230  NK_ASSERT(ctx->current->layout);
19231  if (!ctx || !ctx->current || !ctx->current->layout)
19232  return;
19233 
19234  /* spacing over row boundaries */
19235  win = ctx->current;
19236  layout = win->layout;
19237  index = (layout->row.index + cols) % layout->row.columns;
19238  rows = (layout->row.index + cols) / layout->row.columns;
19239  if (rows) {
19240  for (i = 0; i < rows; ++i)
19241  nk_panel_alloc_row(ctx, win);
19242  cols = index;
19243  }
19244  /* non table layout need to allocate space */
19245  if (layout->row.type != NK_LAYOUT_DYNAMIC_FIXED &&
19246  layout->row.type != NK_LAYOUT_STATIC_FIXED) {
19247  for (i = 0; i < cols; ++i)
19248  nk_panel_alloc_space(&none, ctx);
19249  } layout->row.index = index;
19250 }
19251 
19252 
19253 
19254 
19255 
19256 /* ===============================================================
19257  *
19258  * TEXT
19259  *
19260  * ===============================================================*/
19261 NK_LIB void
19262 nk_widget_text(struct nk_command_buffer *o, struct nk_rect b,
19263  const char *string, int len, const struct nk_text *t,
19264  nk_flags a, const struct nk_user_font *f)
19265 {
19266  struct nk_rect label;
19267  float text_width;
19268 
19269  NK_ASSERT(o);
19270  NK_ASSERT(t);
19271  if (!o || !t) return;
19272 
19273  b.h = NK_MAX(b.h, 2 * t->padding.y);
19274  label.x = 0; label.w = 0;
19275  label.y = b.y + t->padding.y;
19276  label.h = NK_MIN(f->height, b.h - 2 * t->padding.y);
19277 
19278  text_width = f->width(f->userdata, f->height, (const char*)string, len);
19279  text_width += (2.0f * t->padding.x);
19280 
19281  /* align in x-axis */
19282  if (a & NK_TEXT_ALIGN_LEFT) {
19283  label.x = b.x + t->padding.x;
19284  label.w = NK_MAX(0, b.w - 2 * t->padding.x);
19285  } else if (a & NK_TEXT_ALIGN_CENTERED) {
19286  label.w = NK_MAX(1, 2 * t->padding.x + (float)text_width);
19287  label.x = (b.x + t->padding.x + ((b.w - 2 * t->padding.x) - label.w) / 2);
19288  label.x = NK_MAX(b.x + t->padding.x, label.x);
19289  label.w = NK_MIN(b.x + b.w, label.x + label.w);
19290  if (label.w >= label.x) label.w -= label.x;
19291  } else if (a & NK_TEXT_ALIGN_RIGHT) {
19292  label.x = NK_MAX(b.x + t->padding.x, (b.x + b.w) - (2 * t->padding.x + (float)text_width));
19293  label.w = (float)text_width + 2 * t->padding.x;
19294  } else return;
19295 
19296  /* align in y-axis */
19297  if (a & NK_TEXT_ALIGN_MIDDLE) {
19298  label.y = b.y + b.h/2.0f - (float)f->height/2.0f;
19299  label.h = NK_MAX(b.h/2.0f, b.h - (b.h/2.0f + f->height/2.0f));
19300  } else if (a & NK_TEXT_ALIGN_BOTTOM) {
19301  label.y = b.y + b.h - f->height;
19302  label.h = f->height;
19303  }
19304  nk_draw_text(o, label, (const char*)string, len, f, t->background, t->text);
19305 }
19306 NK_LIB void
19307 nk_widget_text_wrap(struct nk_command_buffer *o, struct nk_rect b,
19308  const char *string, int len, const struct nk_text *t,
19309  const struct nk_user_font *f)
19310 {
19311  float width;
19312  int glyphs = 0;
19313  int fitting = 0;
19314  int done = 0;
19315  struct nk_rect line;
19316  struct nk_text text;
19317  NK_INTERN nk_rune seperator[] = {' '};
19318 
19319  NK_ASSERT(o);
19320  NK_ASSERT(t);
19321  if (!o || !t) return;
19322 
19323  text.padding = nk_vec2(0,0);
19324  text.background = t->background;
19325  text.text = t->text;
19326 
19327  b.w = NK_MAX(b.w, 2 * t->padding.x);
19328  b.h = NK_MAX(b.h, 2 * t->padding.y);
19329  b.h = b.h - 2 * t->padding.y;
19330 
19331  line.x = b.x + t->padding.x;
19332  line.y = b.y + t->padding.y;
19333  line.w = b.w - 2 * t->padding.x;
19334  line.h = 2 * t->padding.y + f->height;
19335 
19336  fitting = nk_text_clamp(f, string, len, line.w, &glyphs, &width, seperator,NK_LEN(seperator));
19337  while (done < len) {
19338  if (!fitting || line.y + line.h >= (b.y + b.h)) break;
19339  nk_widget_text(o, line, &string[done], fitting, &text, NK_TEXT_LEFT, f);
19340  done += fitting;
19341  line.y += f->height + 2 * t->padding.y;
19342  fitting = nk_text_clamp(f, &string[done], len - done, line.w, &glyphs, &width, seperator,NK_LEN(seperator));
19343  }
19344 }
19345 NK_API void
19346 nk_text_colored(struct nk_context *ctx, const char *str, int len,
19347  nk_flags alignment, struct nk_color color)
19348 {
19349  struct nk_window *win;
19350  const struct nk_style *style;
19351 
19352  struct nk_vec2 item_padding;
19353  struct nk_rect bounds;
19354  struct nk_text text;
19355 
19356  NK_ASSERT(ctx);
19357  NK_ASSERT(ctx->current);
19358  NK_ASSERT(ctx->current->layout);
19359  if (!ctx || !ctx->current || !ctx->current->layout) return;
19360 
19361  win = ctx->current;
19362  style = &ctx->style;
19363  nk_panel_alloc_space(&bounds, ctx);
19364  item_padding = style->text.padding;
19365 
19366  text.padding.x = item_padding.x;
19367  text.padding.y = item_padding.y;
19368  text.background = style->window.background;
19369  text.text = color;
19370  nk_widget_text(&win->buffer, bounds, str, len, &text, alignment, style->font);
19371 }
19372 NK_API void
19373 nk_text_wrap_colored(struct nk_context *ctx, const char *str,
19374  int len, struct nk_color color)
19375 {
19376  struct nk_window *win;
19377  const struct nk_style *style;
19378 
19379  struct nk_vec2 item_padding;
19380  struct nk_rect bounds;
19381  struct nk_text text;
19382 
19383  NK_ASSERT(ctx);
19384  NK_ASSERT(ctx->current);
19385  NK_ASSERT(ctx->current->layout);
19386  if (!ctx || !ctx->current || !ctx->current->layout) return;
19387 
19388  win = ctx->current;
19389  style = &ctx->style;
19390  nk_panel_alloc_space(&bounds, ctx);
19391  item_padding = style->text.padding;
19392 
19393  text.padding.x = item_padding.x;
19394  text.padding.y = item_padding.y;
19395  text.background = style->window.background;
19396  text.text = color;
19397  nk_widget_text_wrap(&win->buffer, bounds, str, len, &text, style->font);
19398 }
19399 #ifdef NK_INCLUDE_STANDARD_VARARGS
19400 NK_API void
19401 nk_labelf_colored(struct nk_context *ctx, nk_flags flags,
19402  struct nk_color color, const char *fmt, ...)
19403 {
19404  va_list args;
19405  va_start(args, fmt);
19406  nk_labelfv_colored(ctx, flags, color, fmt, args);
19407  va_end(args);
19408 }
19409 NK_API void
19410 nk_labelf_colored_wrap(struct nk_context *ctx, struct nk_color color,
19411  const char *fmt, ...)
19412 {
19413  va_list args;
19414  va_start(args, fmt);
19415  nk_labelfv_colored_wrap(ctx, color, fmt, args);
19416  va_end(args);
19417 }
19418 NK_API void
19419 nk_labelf(struct nk_context *ctx, nk_flags flags, const char *fmt, ...)
19420 {
19421  va_list args;
19422  va_start(args, fmt);
19423  nk_labelfv(ctx, flags, fmt, args);
19424  va_end(args);
19425 }
19426 NK_API void
19427 nk_labelf_wrap(struct nk_context *ctx, const char *fmt,...)
19428 {
19429  va_list args;
19430  va_start(args, fmt);
19431  nk_labelfv_wrap(ctx, fmt, args);
19432  va_end(args);
19433 }
19434 NK_API void
19435 nk_labelfv_colored(struct nk_context *ctx, nk_flags flags,
19436  struct nk_color color, const char *fmt, va_list args)
19437 {
19438  char buf[256];
19439  nk_strfmt(buf, NK_LEN(buf), fmt, args);
19440  nk_label_colored(ctx, buf, flags, color);
19441 }
19442 
19443 NK_API void
19444 nk_labelfv_colored_wrap(struct nk_context *ctx, struct nk_color color,
19445  const char *fmt, va_list args)
19446 {
19447  char buf[256];
19448  nk_strfmt(buf, NK_LEN(buf), fmt, args);
19449  nk_label_colored_wrap(ctx, buf, color);
19450 }
19451 
19452 NK_API void
19453 nk_labelfv(struct nk_context *ctx, nk_flags flags, const char *fmt, va_list args)
19454 {
19455  char buf[256];
19456  nk_strfmt(buf, NK_LEN(buf), fmt, args);
19457  nk_label(ctx, buf, flags);
19458 }
19459 
19460 NK_API void
19461 nk_labelfv_wrap(struct nk_context *ctx, const char *fmt, va_list args)
19462 {
19463  char buf[256];
19464  nk_strfmt(buf, NK_LEN(buf), fmt, args);
19465  nk_label_wrap(ctx, buf);
19466 }
19467 
19468 NK_API void
19469 nk_value_bool(struct nk_context *ctx, const char *prefix, int value)
19470 {
19471  nk_labelf(ctx, NK_TEXT_LEFT, "%s: %s", prefix, ((value) ? "true": "false"));
19472 }
19473 NK_API void
19474 nk_value_int(struct nk_context *ctx, const char *prefix, int value)
19475 {
19476  nk_labelf(ctx, NK_TEXT_LEFT, "%s: %d", prefix, value);
19477 }
19478 NK_API void
19479 nk_value_uint(struct nk_context *ctx, const char *prefix, unsigned int value)
19480 {
19481  nk_labelf(ctx, NK_TEXT_LEFT, "%s: %u", prefix, value);
19482 }
19483 NK_API void
19484 nk_value_float(struct nk_context *ctx, const char *prefix, float value)
19485 {
19486  double double_value = (double)value;
19487  nk_labelf(ctx, NK_TEXT_LEFT, "%s: %.3f", prefix, double_value);
19488 }
19489 NK_API void
19490 nk_value_color_byte(struct nk_context *ctx, const char *p, struct nk_color c)
19491 {
19492  nk_labelf(ctx, NK_TEXT_LEFT, "%s: (%d, %d, %d, %d)", p, c.r, c.g, c.b, c.a);
19493 }
19494 NK_API void
19495 nk_value_color_float(struct nk_context *ctx, const char *p, struct nk_color color)
19496 {
19497  double c[4]; nk_color_dv(c, color);
19498  nk_labelf(ctx, NK_TEXT_LEFT, "%s: (%.2f, %.2f, %.2f, %.2f)",
19499  p, c[0], c[1], c[2], c[3]);
19500 }
19501 NK_API void
19502 nk_value_color_hex(struct nk_context *ctx, const char *prefix, struct nk_color color)
19503 {
19504  char hex[16];
19505  nk_color_hex_rgba(hex, color);
19506  nk_labelf(ctx, NK_TEXT_LEFT, "%s: %s", prefix, hex);
19507 }
19508 #endif
19509 NK_API void
19510 nk_text(struct nk_context *ctx, const char *str, int len, nk_flags alignment)
19511 {
19512  NK_ASSERT(ctx);
19513  if (!ctx) return;
19514  nk_text_colored(ctx, str, len, alignment, ctx->style.text.color);
19515 }
19516 NK_API void
19517 nk_text_wrap(struct nk_context *ctx, const char *str, int len)
19518 {
19519  NK_ASSERT(ctx);
19520  if (!ctx) return;
19521  nk_text_wrap_colored(ctx, str, len, ctx->style.text.color);
19522 }
19523 NK_API void
19524 nk_label(struct nk_context *ctx, const char *str, nk_flags alignment)
19525 {
19526  nk_text(ctx, str, nk_strlen(str), alignment);
19527 }
19528 NK_API void
19529 nk_label_colored(struct nk_context *ctx, const char *str, nk_flags align,
19530  struct nk_color color)
19531 {
19532  nk_text_colored(ctx, str, nk_strlen(str), align, color);
19533 }
19534 NK_API void
19535 nk_label_wrap(struct nk_context *ctx, const char *str)
19536 {
19537  nk_text_wrap(ctx, str, nk_strlen(str));
19538 }
19539 NK_API void
19540 nk_label_colored_wrap(struct nk_context *ctx, const char *str, struct nk_color color)
19541 {
19542  nk_text_wrap_colored(ctx, str, nk_strlen(str), color);
19543 }
19544 
19545 
19546 
19547 
19548 
19549 /* ===============================================================
19550  *
19551  * IMAGE
19552  *
19553  * ===============================================================*/
19555 nk_handle_ptr(void *ptr)
19556 {
19557  nk_handle handle = {0};
19558  handle.ptr = ptr;
19559  return handle;
19560 }
19562 nk_handle_id(int id)
19563 {
19564  nk_handle handle;
19565  nk_zero_struct(handle);
19566  handle.id = id;
19567  return handle;
19568 }
19569 NK_API struct nk_image
19570 nk_subimage_ptr(void *ptr, unsigned short w, unsigned short h, struct nk_rect r)
19571 {
19572  struct nk_image s;
19573  nk_zero(&s, sizeof(s));
19574  s.handle.ptr = ptr;
19575  s.w = w; s.h = h;
19576  s.region[0] = (unsigned short)r.x;
19577  s.region[1] = (unsigned short)r.y;
19578  s.region[2] = (unsigned short)r.w;
19579  s.region[3] = (unsigned short)r.h;
19580  return s;
19581 }
19582 NK_API struct nk_image
19583 nk_subimage_id(int id, unsigned short w, unsigned short h, struct nk_rect r)
19584 {
19585  struct nk_image s;
19586  nk_zero(&s, sizeof(s));
19587  s.handle.id = id;
19588  s.w = w; s.h = h;
19589  s.region[0] = (unsigned short)r.x;
19590  s.region[1] = (unsigned short)r.y;
19591  s.region[2] = (unsigned short)r.w;
19592  s.region[3] = (unsigned short)r.h;
19593  return s;
19594 }
19595 NK_API struct nk_image
19596 nk_subimage_handle(nk_handle handle, unsigned short w, unsigned short h,
19597  struct nk_rect r)
19598 {
19599  struct nk_image s;
19600  nk_zero(&s, sizeof(s));
19601  s.handle = handle;
19602  s.w = w; s.h = h;
19603  s.region[0] = (unsigned short)r.x;
19604  s.region[1] = (unsigned short)r.y;
19605  s.region[2] = (unsigned short)r.w;
19606  s.region[3] = (unsigned short)r.h;
19607  return s;
19608 }
19609 NK_API struct nk_image
19611 {
19612  struct nk_image s;
19613  nk_zero(&s, sizeof(s));
19614  s.handle = handle;
19615  s.w = 0; s.h = 0;
19616  s.region[0] = 0;
19617  s.region[1] = 0;
19618  s.region[2] = 0;
19619  s.region[3] = 0;
19620  return s;
19621 }
19622 NK_API struct nk_image
19623 nk_image_ptr(void *ptr)
19624 {
19625  struct nk_image s;
19626  nk_zero(&s, sizeof(s));
19627  NK_ASSERT(ptr);
19628  s.handle.ptr = ptr;
19629  s.w = 0; s.h = 0;
19630  s.region[0] = 0;
19631  s.region[1] = 0;
19632  s.region[2] = 0;
19633  s.region[3] = 0;
19634  return s;
19635 }
19636 NK_API struct nk_image
19637 nk_image_id(int id)
19638 {
19639  struct nk_image s;
19640  nk_zero(&s, sizeof(s));
19641  s.handle.id = id;
19642  s.w = 0; s.h = 0;
19643  s.region[0] = 0;
19644  s.region[1] = 0;
19645  s.region[2] = 0;
19646  s.region[3] = 0;
19647  return s;
19648 }
19649 NK_API int
19650 nk_image_is_subimage(const struct nk_image* img)
19651 {
19652  NK_ASSERT(img);
19653  return !(img->w == 0 && img->h == 0);
19654 }
19655 NK_API void
19656 nk_image(struct nk_context *ctx, struct nk_image img)
19657 {
19658  struct nk_window *win;
19659  struct nk_rect bounds;
19660 
19661  NK_ASSERT(ctx);
19662  NK_ASSERT(ctx->current);
19663  NK_ASSERT(ctx->current->layout);
19664  if (!ctx || !ctx->current || !ctx->current->layout) return;
19665 
19666  win = ctx->current;
19667  if (!nk_widget(&bounds, ctx)) return;
19668  nk_draw_image(&win->buffer, bounds, &img, nk_white);
19669 }
19670 NK_API void
19671 nk_image_color(struct nk_context *ctx, struct nk_image img, struct nk_color col)
19672 {
19673  struct nk_window *win;
19674  struct nk_rect bounds;
19675 
19676  NK_ASSERT(ctx);
19677  NK_ASSERT(ctx->current);
19678  NK_ASSERT(ctx->current->layout);
19679  if (!ctx || !ctx->current || !ctx->current->layout) return;
19680 
19681  win = ctx->current;
19682  if (!nk_widget(&bounds, ctx)) return;
19683  nk_draw_image(&win->buffer, bounds, &img, col);
19684 }
19685 
19686 
19687 
19688 
19689 
19690 /* ==============================================================
19691  *
19692  * BUTTON
19693  *
19694  * ===============================================================*/
19695 NK_LIB void
19696 nk_draw_symbol(struct nk_command_buffer *out, enum nk_symbol_type type,
19697  struct nk_rect content, struct nk_color background, struct nk_color foreground,
19698  float border_width, const struct nk_user_font *font)
19699 {
19700  switch (type) {
19701  case NK_SYMBOL_X:
19702  case NK_SYMBOL_UNDERSCORE:
19703  case NK_SYMBOL_PLUS:
19704  case NK_SYMBOL_MINUS: {
19705  /* single character text symbol */
19706  const char *X = (type == NK_SYMBOL_X) ? "x":
19707  (type == NK_SYMBOL_UNDERSCORE) ? "_":
19708  (type == NK_SYMBOL_PLUS) ? "+": "-";
19709  struct nk_text text;
19710  text.padding = nk_vec2(0,0);
19711  text.background = background;
19712  text.text = foreground;
19713  nk_widget_text(out, content, X, 1, &text, NK_TEXT_CENTERED, font);
19714  } break;
19717  case NK_SYMBOL_RECT_SOLID:
19718  case NK_SYMBOL_RECT_OUTLINE: {
19719  /* simple empty/filled shapes */
19720  if (type == NK_SYMBOL_RECT_SOLID || type == NK_SYMBOL_RECT_OUTLINE) {
19721  nk_fill_rect(out, content, 0, foreground);
19722  if (type == NK_SYMBOL_RECT_OUTLINE)
19723  nk_fill_rect(out, nk_shrink_rect(content, border_width), 0, background);
19724  } else {
19725  nk_fill_circle(out, content, foreground);
19726  if (type == NK_SYMBOL_CIRCLE_OUTLINE)
19727  nk_fill_circle(out, nk_shrink_rect(content, 1), background);
19728  }
19729  } break;
19730  case NK_SYMBOL_TRIANGLE_UP:
19733  case NK_SYMBOL_TRIANGLE_RIGHT: {
19734  enum nk_heading heading;
19735  struct nk_vec2 points[3];
19736  heading = (type == NK_SYMBOL_TRIANGLE_RIGHT) ? NK_RIGHT :
19737  (type == NK_SYMBOL_TRIANGLE_LEFT) ? NK_LEFT:
19738  (type == NK_SYMBOL_TRIANGLE_UP) ? NK_UP: NK_DOWN;
19739  nk_triangle_from_direction(points, content, 0, 0, heading);
19740  nk_fill_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y,
19741  points[2].x, points[2].y, foreground);
19742  } break;
19743  default:
19744  case NK_SYMBOL_NONE:
19745  case NK_SYMBOL_MAX: break;
19746  }
19747 }
19748 NK_LIB int
19749 nk_button_behavior(nk_flags *state, struct nk_rect r,
19750  const struct nk_input *i, enum nk_button_behavior behavior)
19751 {
19752  int ret = 0;
19753  nk_widget_state_reset(state);
19754  if (!i) return 0;
19755  if (nk_input_is_mouse_hovering_rect(i, r)) {
19756  *state = NK_WIDGET_STATE_HOVERED;
19758  *state = NK_WIDGET_STATE_ACTIVE;
19760  ret = (behavior != NK_BUTTON_DEFAULT) ?
19762 #ifdef NK_BUTTON_TRIGGER_ON_RELEASE
19764 #else
19766 #endif
19767  }
19768  }
19770  *state |= NK_WIDGET_STATE_ENTERED;
19771  else if (nk_input_is_mouse_prev_hovering_rect(i, r))
19772  *state |= NK_WIDGET_STATE_LEFT;
19773  return ret;
19774 }
19775 NK_LIB const struct nk_style_item*
19776 nk_draw_button(struct nk_command_buffer *out,
19777  const struct nk_rect *bounds, nk_flags state,
19778  const struct nk_style_button *style)
19779 {
19780  const struct nk_style_item *background;
19781  if (state & NK_WIDGET_STATE_HOVER)
19782  background = &style->hover;
19783  else if (state & NK_WIDGET_STATE_ACTIVED)
19784  background = &style->active;
19785  else background = &style->normal;
19786 
19787  if (background->type == NK_STYLE_ITEM_IMAGE) {
19788  nk_draw_image(out, *bounds, &background->data.image, nk_white);
19789  } else {
19790  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
19791  nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
19792  }
19793  return background;
19794 }
19795 NK_LIB int
19796 nk_do_button(nk_flags *state, struct nk_command_buffer *out, struct nk_rect r,
19797  const struct nk_style_button *style, const struct nk_input *in,
19798  enum nk_button_behavior behavior, struct nk_rect *content)
19799 {
19800  struct nk_rect bounds;
19801  NK_ASSERT(style);
19802  NK_ASSERT(state);
19803  NK_ASSERT(out);
19804  if (!out || !style)
19805  return nk_false;
19806 
19807  /* calculate button content space */
19808  content->x = r.x + style->padding.x + style->border + style->rounding;
19809  content->y = r.y + style->padding.y + style->border + style->rounding;
19810  content->w = r.w - (2 * style->padding.x + style->border + style->rounding*2);
19811  content->h = r.h - (2 * style->padding.y + style->border + style->rounding*2);
19812 
19813  /* execute button behavior */
19814  bounds.x = r.x - style->touch_padding.x;
19815  bounds.y = r.y - style->touch_padding.y;
19816  bounds.w = r.w + 2 * style->touch_padding.x;
19817  bounds.h = r.h + 2 * style->touch_padding.y;
19818  return nk_button_behavior(state, bounds, in, behavior);
19819 }
19820 NK_LIB void
19821 nk_draw_button_text(struct nk_command_buffer *out,
19822  const struct nk_rect *bounds, const struct nk_rect *content, nk_flags state,
19823  const struct nk_style_button *style, const char *txt, int len,
19824  nk_flags text_alignment, const struct nk_user_font *font)
19825 {
19826  struct nk_text text;
19827  const struct nk_style_item *background;
19828  background = nk_draw_button(out, bounds, state, style);
19829 
19830  /* select correct colors/images */
19831  if (background->type == NK_STYLE_ITEM_COLOR)
19832  text.background = background->data.color;
19833  else text.background = style->text_background;
19834  if (state & NK_WIDGET_STATE_HOVER)
19835  text.text = style->text_hover;
19836  else if (state & NK_WIDGET_STATE_ACTIVED)
19837  text.text = style->text_active;
19838  else text.text = style->text_normal;
19839 
19840  text.padding = nk_vec2(0,0);
19841  nk_widget_text(out, *content, txt, len, &text, text_alignment, font);
19842 }
19843 NK_LIB int
19844 nk_do_button_text(nk_flags *state,
19845  struct nk_command_buffer *out, struct nk_rect bounds,
19846  const char *string, int len, nk_flags align, enum nk_button_behavior behavior,
19847  const struct nk_style_button *style, const struct nk_input *in,
19848  const struct nk_user_font *font)
19849 {
19850  struct nk_rect content;
19851  int ret = nk_false;
19852 
19853  NK_ASSERT(state);
19854  NK_ASSERT(style);
19855  NK_ASSERT(out);
19856  NK_ASSERT(string);
19857  NK_ASSERT(font);
19858  if (!out || !style || !font || !string)
19859  return nk_false;
19860 
19861  ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
19862  if (style->draw_begin) style->draw_begin(out, style->userdata);
19863  nk_draw_button_text(out, &bounds, &content, *state, style, string, len, align, font);
19864  if (style->draw_end) style->draw_end(out, style->userdata);
19865  return ret;
19866 }
19867 NK_LIB void
19868 nk_draw_button_symbol(struct nk_command_buffer *out,
19869  const struct nk_rect *bounds, const struct nk_rect *content,
19870  nk_flags state, const struct nk_style_button *style,
19871  enum nk_symbol_type type, const struct nk_user_font *font)
19872 {
19873  struct nk_color sym, bg;
19874  const struct nk_style_item *background;
19875 
19876  /* select correct colors/images */
19877  background = nk_draw_button(out, bounds, state, style);
19878  if (background->type == NK_STYLE_ITEM_COLOR)
19879  bg = background->data.color;
19880  else bg = style->text_background;
19881 
19882  if (state & NK_WIDGET_STATE_HOVER)
19883  sym = style->text_hover;
19884  else if (state & NK_WIDGET_STATE_ACTIVED)
19885  sym = style->text_active;
19886  else sym = style->text_normal;
19887  nk_draw_symbol(out, type, *content, bg, sym, 1, font);
19888 }
19889 NK_LIB int
19890 nk_do_button_symbol(nk_flags *state,
19891  struct nk_command_buffer *out, struct nk_rect bounds,
19892  enum nk_symbol_type symbol, enum nk_button_behavior behavior,
19893  const struct nk_style_button *style, const struct nk_input *in,
19894  const struct nk_user_font *font)
19895 {
19896  int ret;
19897  struct nk_rect content;
19898 
19899  NK_ASSERT(state);
19900  NK_ASSERT(style);
19901  NK_ASSERT(font);
19902  NK_ASSERT(out);
19903  if (!out || !style || !font || !state)
19904  return nk_false;
19905 
19906  ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
19907  if (style->draw_begin) style->draw_begin(out, style->userdata);
19908  nk_draw_button_symbol(out, &bounds, &content, *state, style, symbol, font);
19909  if (style->draw_end) style->draw_end(out, style->userdata);
19910  return ret;
19911 }
19912 NK_LIB void
19913 nk_draw_button_image(struct nk_command_buffer *out,
19914  const struct nk_rect *bounds, const struct nk_rect *content,
19915  nk_flags state, const struct nk_style_button *style, const struct nk_image *img)
19916 {
19917  nk_draw_button(out, bounds, state, style);
19918  nk_draw_image(out, *content, img, nk_white);
19919 }
19920 NK_LIB int
19921 nk_do_button_image(nk_flags *state,
19922  struct nk_command_buffer *out, struct nk_rect bounds,
19923  struct nk_image img, enum nk_button_behavior b,
19924  const struct nk_style_button *style, const struct nk_input *in)
19925 {
19926  int ret;
19927  struct nk_rect content;
19928 
19929  NK_ASSERT(state);
19930  NK_ASSERT(style);
19931  NK_ASSERT(out);
19932  if (!out || !style || !state)
19933  return nk_false;
19934 
19935  ret = nk_do_button(state, out, bounds, style, in, b, &content);
19936  content.x += style->image_padding.x;
19937  content.y += style->image_padding.y;
19938  content.w -= 2 * style->image_padding.x;
19939  content.h -= 2 * style->image_padding.y;
19940 
19941  if (style->draw_begin) style->draw_begin(out, style->userdata);
19942  nk_draw_button_image(out, &bounds, &content, *state, style, &img);
19943  if (style->draw_end) style->draw_end(out, style->userdata);
19944  return ret;
19945 }
19946 NK_LIB void
19947 nk_draw_button_text_symbol(struct nk_command_buffer *out,
19948  const struct nk_rect *bounds, const struct nk_rect *label,
19949  const struct nk_rect *symbol, nk_flags state, const struct nk_style_button *style,
19950  const char *str, int len, enum nk_symbol_type type,
19951  const struct nk_user_font *font)
19952 {
19953  struct nk_color sym;
19954  struct nk_text text;
19955  const struct nk_style_item *background;
19956 
19957  /* select correct background colors/images */
19958  background = nk_draw_button(out, bounds, state, style);
19959  if (background->type == NK_STYLE_ITEM_COLOR)
19960  text.background = background->data.color;
19961  else text.background = style->text_background;
19962 
19963  /* select correct text colors */
19964  if (state & NK_WIDGET_STATE_HOVER) {
19965  sym = style->text_hover;
19966  text.text = style->text_hover;
19967  } else if (state & NK_WIDGET_STATE_ACTIVED) {
19968  sym = style->text_active;
19969  text.text = style->text_active;
19970  } else {
19971  sym = style->text_normal;
19972  text.text = style->text_normal;
19973  }
19974 
19975  text.padding = nk_vec2(0,0);
19976  nk_draw_symbol(out, type, *symbol, style->text_background, sym, 0, font);
19977  nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font);
19978 }
19979 NK_LIB int
19980 nk_do_button_text_symbol(nk_flags *state,
19981  struct nk_command_buffer *out, struct nk_rect bounds,
19982  enum nk_symbol_type symbol, const char *str, int len, nk_flags align,
19983  enum nk_button_behavior behavior, const struct nk_style_button *style,
19984  const struct nk_user_font *font, const struct nk_input *in)
19985 {
19986  int ret;
19987  struct nk_rect tri = {0,0,0,0};
19988  struct nk_rect content;
19989 
19990  NK_ASSERT(style);
19991  NK_ASSERT(out);
19992  NK_ASSERT(font);
19993  if (!out || !style || !font)
19994  return nk_false;
19995 
19996  ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
19997  tri.y = content.y + (content.h/2) - font->height/2;
19998  tri.w = font->height; tri.h = font->height;
19999  if (align & NK_TEXT_ALIGN_LEFT) {
20000  tri.x = (content.x + content.w) - (2 * style->padding.x + tri.w);
20001  tri.x = NK_MAX(tri.x, 0);
20002  } else tri.x = content.x + 2 * style->padding.x;
20003 
20004  /* draw button */
20005  if (style->draw_begin) style->draw_begin(out, style->userdata);
20006  nk_draw_button_text_symbol(out, &bounds, &content, &tri,
20007  *state, style, str, len, symbol, font);
20008  if (style->draw_end) style->draw_end(out, style->userdata);
20009  return ret;
20010 }
20011 NK_LIB void
20012 nk_draw_button_text_image(struct nk_command_buffer *out,
20013  const struct nk_rect *bounds, const struct nk_rect *label,
20014  const struct nk_rect *image, nk_flags state, const struct nk_style_button *style,
20015  const char *str, int len, const struct nk_user_font *font,
20016  const struct nk_image *img)
20017 {
20018  struct nk_text text;
20019  const struct nk_style_item *background;
20020  background = nk_draw_button(out, bounds, state, style);
20021 
20022  /* select correct colors */
20023  if (background->type == NK_STYLE_ITEM_COLOR)
20024  text.background = background->data.color;
20025  else text.background = style->text_background;
20026  if (state & NK_WIDGET_STATE_HOVER)
20027  text.text = style->text_hover;
20028  else if (state & NK_WIDGET_STATE_ACTIVED)
20029  text.text = style->text_active;
20030  else text.text = style->text_normal;
20031 
20032  text.padding = nk_vec2(0,0);
20033  nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font);
20034  nk_draw_image(out, *image, img, nk_white);
20035 }
20036 NK_LIB int
20037 nk_do_button_text_image(nk_flags *state,
20038  struct nk_command_buffer *out, struct nk_rect bounds,
20039  struct nk_image img, const char* str, int len, nk_flags align,
20040  enum nk_button_behavior behavior, const struct nk_style_button *style,
20041  const struct nk_user_font *font, const struct nk_input *in)
20042 {
20043  int ret;
20044  struct nk_rect icon;
20045  struct nk_rect content;
20046 
20047  NK_ASSERT(style);
20048  NK_ASSERT(state);
20049  NK_ASSERT(font);
20050  NK_ASSERT(out);
20051  if (!out || !font || !style || !str)
20052  return nk_false;
20053 
20054  ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
20055  icon.y = bounds.y + style->padding.y;
20056  icon.w = icon.h = bounds.h - 2 * style->padding.y;
20057  if (align & NK_TEXT_ALIGN_LEFT) {
20058  icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
20059  icon.x = NK_MAX(icon.x, 0);
20060  } else icon.x = bounds.x + 2 * style->padding.x;
20061 
20062  icon.x += style->image_padding.x;
20063  icon.y += style->image_padding.y;
20064  icon.w -= 2 * style->image_padding.x;
20065  icon.h -= 2 * style->image_padding.y;
20066 
20067  if (style->draw_begin) style->draw_begin(out, style->userdata);
20068  nk_draw_button_text_image(out, &bounds, &content, &icon, *state, style, str, len, font, &img);
20069  if (style->draw_end) style->draw_end(out, style->userdata);
20070  return ret;
20071 }
20072 NK_API void
20074 {
20075  NK_ASSERT(ctx);
20076  if (!ctx) return;
20077  ctx->button_behavior = behavior;
20078 }
20079 NK_API int
20081 {
20082  struct nk_config_stack_button_behavior *button_stack;
20083  struct nk_config_stack_button_behavior_element *element;
20084 
20085  NK_ASSERT(ctx);
20086  if (!ctx) return 0;
20087 
20088  button_stack = &ctx->stacks.button_behaviors;
20089  NK_ASSERT(button_stack->head < (int)NK_LEN(button_stack->elements));
20090  if (button_stack->head >= (int)NK_LEN(button_stack->elements))
20091  return 0;
20092 
20093  element = &button_stack->elements[button_stack->head++];
20094  element->address = &ctx->button_behavior;
20095  element->old_value = ctx->button_behavior;
20096  ctx->button_behavior = behavior;
20097  return 1;
20098 }
20099 NK_API int
20101 {
20102  struct nk_config_stack_button_behavior *button_stack;
20103  struct nk_config_stack_button_behavior_element *element;
20104 
20105  NK_ASSERT(ctx);
20106  if (!ctx) return 0;
20107 
20108  button_stack = &ctx->stacks.button_behaviors;
20109  NK_ASSERT(button_stack->head > 0);
20110  if (button_stack->head < 1)
20111  return 0;
20112 
20113  element = &button_stack->elements[--button_stack->head];
20114  *element->address = element->old_value;
20115  return 1;
20116 }
20117 NK_API int
20119  const struct nk_style_button *style, const char *title, int len)
20120 {
20121  struct nk_window *win;
20122  struct nk_panel *layout;
20123  const struct nk_input *in;
20124 
20125  struct nk_rect bounds;
20126  enum nk_widget_layout_states state;
20127 
20128  NK_ASSERT(ctx);
20129  NK_ASSERT(style);
20130  NK_ASSERT(ctx->current);
20131  NK_ASSERT(ctx->current->layout);
20132  if (!style || !ctx || !ctx->current || !ctx->current->layout) return 0;
20133 
20134  win = ctx->current;
20135  layout = win->layout;
20136  state = nk_widget(&bounds, ctx);
20137 
20138  if (!state) return 0;
20139  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20140  return nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds,
20141  title, len, style->text_alignment, ctx->button_behavior,
20142  style, in, ctx->style.font);
20143 }
20144 NK_API int
20145 nk_button_text(struct nk_context *ctx, const char *title, int len)
20146 {
20147  NK_ASSERT(ctx);
20148  if (!ctx) return 0;
20149  return nk_button_text_styled(ctx, &ctx->style.button, title, len);
20150 }
20152  const struct nk_style_button *style, const char *title)
20153 {
20154  return nk_button_text_styled(ctx, style, title, nk_strlen(title));
20155 }
20156 NK_API int nk_button_label(struct nk_context *ctx, const char *title)
20157 {
20158  return nk_button_text(ctx, title, nk_strlen(title));
20159 }
20160 NK_API int
20161 nk_button_color(struct nk_context *ctx, struct nk_color color)
20162 {
20163  struct nk_window *win;
20164  struct nk_panel *layout;
20165  const struct nk_input *in;
20166  struct nk_style_button button;
20167 
20168  int ret = 0;
20169  struct nk_rect bounds;
20170  struct nk_rect content;
20171  enum nk_widget_layout_states state;
20172 
20173  NK_ASSERT(ctx);
20174  NK_ASSERT(ctx->current);
20175  NK_ASSERT(ctx->current->layout);
20176  if (!ctx || !ctx->current || !ctx->current->layout)
20177  return 0;
20178 
20179  win = ctx->current;
20180  layout = win->layout;
20181 
20182  state = nk_widget(&bounds, ctx);
20183  if (!state) return 0;
20184  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20185 
20186  button = ctx->style.button;
20187  button.normal = nk_style_item_color(color);
20188  button.hover = nk_style_item_color(color);
20189  button.active = nk_style_item_color(color);
20190  ret = nk_do_button(&ctx->last_widget_state, &win->buffer, bounds,
20191  &button, in, ctx->button_behavior, &content);
20192  nk_draw_button(&win->buffer, &bounds, ctx->last_widget_state, &button);
20193  return ret;
20194 }
20195 NK_API int
20197  const struct nk_style_button *style, enum nk_symbol_type symbol)
20198 {
20199  struct nk_window *win;
20200  struct nk_panel *layout;
20201  const struct nk_input *in;
20202 
20203  struct nk_rect bounds;
20204  enum nk_widget_layout_states state;
20205 
20206  NK_ASSERT(ctx);
20207  NK_ASSERT(ctx->current);
20208  NK_ASSERT(ctx->current->layout);
20209  if (!ctx || !ctx->current || !ctx->current->layout)
20210  return 0;
20211 
20212  win = ctx->current;
20213  layout = win->layout;
20214  state = nk_widget(&bounds, ctx);
20215  if (!state) return 0;
20216  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20217  return nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, bounds,
20218  symbol, ctx->button_behavior, style, in, ctx->style.font);
20219 }
20220 NK_API int
20221 nk_button_symbol(struct nk_context *ctx, enum nk_symbol_type symbol)
20222 {
20223  NK_ASSERT(ctx);
20224  if (!ctx) return 0;
20225  return nk_button_symbol_styled(ctx, &ctx->style.button, symbol);
20226 }
20227 NK_API int
20228 nk_button_image_styled(struct nk_context *ctx, const struct nk_style_button *style,
20229  struct nk_image img)
20230 {
20231  struct nk_window *win;
20232  struct nk_panel *layout;
20233  const struct nk_input *in;
20234 
20235  struct nk_rect bounds;
20236  enum nk_widget_layout_states state;
20237 
20238  NK_ASSERT(ctx);
20239  NK_ASSERT(ctx->current);
20240  NK_ASSERT(ctx->current->layout);
20241  if (!ctx || !ctx->current || !ctx->current->layout)
20242  return 0;
20243 
20244  win = ctx->current;
20245  layout = win->layout;
20246 
20247  state = nk_widget(&bounds, ctx);
20248  if (!state) return 0;
20249  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20250  return nk_do_button_image(&ctx->last_widget_state, &win->buffer, bounds,
20251  img, ctx->button_behavior, style, in);
20252 }
20253 NK_API int
20254 nk_button_image(struct nk_context *ctx, struct nk_image img)
20255 {
20256  NK_ASSERT(ctx);
20257  if (!ctx) return 0;
20258  return nk_button_image_styled(ctx, &ctx->style.button, img);
20259 }
20260 NK_API int
20262  const struct nk_style_button *style, enum nk_symbol_type symbol,
20263  const char *text, int len, nk_flags align)
20264 {
20265  struct nk_window *win;
20266  struct nk_panel *layout;
20267  const struct nk_input *in;
20268 
20269  struct nk_rect bounds;
20270  enum nk_widget_layout_states state;
20271 
20272  NK_ASSERT(ctx);
20273  NK_ASSERT(ctx->current);
20274  NK_ASSERT(ctx->current->layout);
20275  if (!ctx || !ctx->current || !ctx->current->layout)
20276  return 0;
20277 
20278  win = ctx->current;
20279  layout = win->layout;
20280 
20281  state = nk_widget(&bounds, ctx);
20282  if (!state) return 0;
20283  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20284  return nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds,
20285  symbol, text, len, align, ctx->button_behavior,
20286  style, ctx->style.font, in);
20287 }
20288 NK_API int
20289 nk_button_symbol_text(struct nk_context *ctx, enum nk_symbol_type symbol,
20290  const char* text, int len, nk_flags align)
20291 {
20292  NK_ASSERT(ctx);
20293  if (!ctx) return 0;
20294  return nk_button_symbol_text_styled(ctx, &ctx->style.button, symbol, text, len, align);
20295 }
20296 NK_API int nk_button_symbol_label(struct nk_context *ctx, enum nk_symbol_type symbol,
20297  const char *label, nk_flags align)
20298 {
20299  return nk_button_symbol_text(ctx, symbol, label, nk_strlen(label), align);
20300 }
20302  const struct nk_style_button *style, enum nk_symbol_type symbol,
20303  const char *title, nk_flags align)
20304 {
20305  return nk_button_symbol_text_styled(ctx, style, symbol, title, nk_strlen(title), align);
20306 }
20307 NK_API int
20309  const struct nk_style_button *style, struct nk_image img, const char *text,
20310  int len, nk_flags align)
20311 {
20312  struct nk_window *win;
20313  struct nk_panel *layout;
20314  const struct nk_input *in;
20315 
20316  struct nk_rect bounds;
20317  enum nk_widget_layout_states state;
20318 
20319  NK_ASSERT(ctx);
20320  NK_ASSERT(ctx->current);
20321  NK_ASSERT(ctx->current->layout);
20322  if (!ctx || !ctx->current || !ctx->current->layout)
20323  return 0;
20324 
20325  win = ctx->current;
20326  layout = win->layout;
20327 
20328  state = nk_widget(&bounds, ctx);
20329  if (!state) return 0;
20330  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20331  return nk_do_button_text_image(&ctx->last_widget_state, &win->buffer,
20332  bounds, img, text, len, align, ctx->button_behavior,
20333  style, ctx->style.font, in);
20334 }
20335 NK_API int
20336 nk_button_image_text(struct nk_context *ctx, struct nk_image img,
20337  const char *text, int len, nk_flags align)
20338 {
20339  return nk_button_image_text_styled(ctx, &ctx->style.button,img, text, len, align);
20340 }
20341 NK_API int nk_button_image_label(struct nk_context *ctx, struct nk_image img,
20342  const char *label, nk_flags align)
20343 {
20344  return nk_button_image_text(ctx, img, label, nk_strlen(label), align);
20345 }
20347  const struct nk_style_button *style, struct nk_image img,
20348  const char *label, nk_flags text_alignment)
20349 {
20350  return nk_button_image_text_styled(ctx, style, img, label, nk_strlen(label), text_alignment);
20351 }
20352 
20353 
20354 
20355 
20356 
20357 /* ===============================================================
20358  *
20359  * TOGGLE
20360  *
20361  * ===============================================================*/
20362 NK_LIB int
20363 nk_toggle_behavior(const struct nk_input *in, struct nk_rect select,
20364  nk_flags *state, int active)
20365 {
20366  nk_widget_state_reset(state);
20367  if (nk_button_behavior(state, select, in, NK_BUTTON_DEFAULT)) {
20368  *state = NK_WIDGET_STATE_ACTIVE;
20369  active = !active;
20370  }
20371  if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, select))
20372  *state |= NK_WIDGET_STATE_ENTERED;
20373  else if (nk_input_is_mouse_prev_hovering_rect(in, select))
20374  *state |= NK_WIDGET_STATE_LEFT;
20375  return active;
20376 }
20377 NK_LIB void
20378 nk_draw_checkbox(struct nk_command_buffer *out,
20379  nk_flags state, const struct nk_style_toggle *style, int active,
20380  const struct nk_rect *label, const struct nk_rect *selector,
20381  const struct nk_rect *cursors, const char *string, int len,
20382  const struct nk_user_font *font)
20383 {
20384  const struct nk_style_item *background;
20385  const struct nk_style_item *cursor;
20386  struct nk_text text;
20387 
20388  /* select correct colors/images */
20389  if (state & NK_WIDGET_STATE_HOVER) {
20390  background = &style->hover;
20391  cursor = &style->cursor_hover;
20392  text.text = style->text_hover;
20393  } else if (state & NK_WIDGET_STATE_ACTIVED) {
20394  background = &style->hover;
20395  cursor = &style->cursor_hover;
20396  text.text = style->text_active;
20397  } else {
20398  background = &style->normal;
20399  cursor = &style->cursor_normal;
20400  text.text = style->text_normal;
20401  }
20402 
20403  /* draw background and cursor */
20404  if (background->type == NK_STYLE_ITEM_COLOR) {
20405  nk_fill_rect(out, *selector, 0, style->border_color);
20406  nk_fill_rect(out, nk_shrink_rect(*selector, style->border), 0, background->data.color);
20407  } else nk_draw_image(out, *selector, &background->data.image, nk_white);
20408  if (active) {
20409  if (cursor->type == NK_STYLE_ITEM_IMAGE)
20410  nk_draw_image(out, *cursors, &cursor->data.image, nk_white);
20411  else nk_fill_rect(out, *cursors, 0, cursor->data.color);
20412  }
20413 
20414  text.padding.x = 0;
20415  text.padding.y = 0;
20416  text.background = style->text_background;
20417  nk_widget_text(out, *label, string, len, &text, NK_TEXT_LEFT, font);
20418 }
20419 NK_LIB void
20420 nk_draw_option(struct nk_command_buffer *out,
20421  nk_flags state, const struct nk_style_toggle *style, int active,
20422  const struct nk_rect *label, const struct nk_rect *selector,
20423  const struct nk_rect *cursors, const char *string, int len,
20424  const struct nk_user_font *font)
20425 {
20426  const struct nk_style_item *background;
20427  const struct nk_style_item *cursor;
20428  struct nk_text text;
20429 
20430  /* select correct colors/images */
20431  if (state & NK_WIDGET_STATE_HOVER) {
20432  background = &style->hover;
20433  cursor = &style->cursor_hover;
20434  text.text = style->text_hover;
20435  } else if (state & NK_WIDGET_STATE_ACTIVED) {
20436  background = &style->hover;
20437  cursor = &style->cursor_hover;
20438  text.text = style->text_active;
20439  } else {
20440  background = &style->normal;
20441  cursor = &style->cursor_normal;
20442  text.text = style->text_normal;
20443  }
20444 
20445  /* draw background and cursor */
20446  if (background->type == NK_STYLE_ITEM_COLOR) {
20447  nk_fill_circle(out, *selector, style->border_color);
20448  nk_fill_circle(out, nk_shrink_rect(*selector, style->border), background->data.color);
20449  } else nk_draw_image(out, *selector, &background->data.image, nk_white);
20450  if (active) {
20451  if (cursor->type == NK_STYLE_ITEM_IMAGE)
20452  nk_draw_image(out, *cursors, &cursor->data.image, nk_white);
20453  else nk_fill_circle(out, *cursors, cursor->data.color);
20454  }
20455 
20456  text.padding.x = 0;
20457  text.padding.y = 0;
20458  text.background = style->text_background;
20459  nk_widget_text(out, *label, string, len, &text, NK_TEXT_LEFT, font);
20460 }
20461 NK_LIB int
20462 nk_do_toggle(nk_flags *state,
20463  struct nk_command_buffer *out, struct nk_rect r,
20464  int *active, const char *str, int len, enum nk_toggle_type type,
20465  const struct nk_style_toggle *style, const struct nk_input *in,
20466  const struct nk_user_font *font)
20467 {
20468  int was_active;
20469  struct nk_rect bounds;
20470  struct nk_rect select;
20471  struct nk_rect cursor;
20472  struct nk_rect label;
20473 
20474  NK_ASSERT(style);
20475  NK_ASSERT(out);
20476  NK_ASSERT(font);
20477  if (!out || !style || !font || !active)
20478  return 0;
20479 
20480  r.w = NK_MAX(r.w, font->height + 2 * style->padding.x);
20481  r.h = NK_MAX(r.h, font->height + 2 * style->padding.y);
20482 
20483  /* add additional touch padding for touch screen devices */
20484  bounds.x = r.x - style->touch_padding.x;
20485  bounds.y = r.y - style->touch_padding.y;
20486  bounds.w = r.w + 2 * style->touch_padding.x;
20487  bounds.h = r.h + 2 * style->touch_padding.y;
20488 
20489  /* calculate the selector space */
20490  select.w = font->height;
20491  select.h = select.w;
20492  select.y = r.y + r.h/2.0f - select.h/2.0f;
20493  select.x = r.x;
20494 
20495  /* calculate the bounds of the cursor inside the selector */
20496  cursor.x = select.x + style->padding.x + style->border;
20497  cursor.y = select.y + style->padding.y + style->border;
20498  cursor.w = select.w - (2 * style->padding.x + 2 * style->border);
20499  cursor.h = select.h - (2 * style->padding.y + 2 * style->border);
20500 
20501  /* label behind the selector */
20502  label.x = select.x + select.w + style->spacing;
20503  label.y = select.y;
20504  label.w = NK_MAX(r.x + r.w, label.x) - label.x;
20505  label.h = select.w;
20506 
20507  /* update selector */
20508  was_active = *active;
20509  *active = nk_toggle_behavior(in, bounds, state, *active);
20510 
20511  /* draw selector */
20512  if (style->draw_begin)
20513  style->draw_begin(out, style->userdata);
20514  if (type == NK_TOGGLE_CHECK) {
20515  nk_draw_checkbox(out, *state, style, *active, &label, &select, &cursor, str, len, font);
20516  } else {
20517  nk_draw_option(out, *state, style, *active, &label, &select, &cursor, str, len, font);
20518  }
20519  if (style->draw_end)
20520  style->draw_end(out, style->userdata);
20521  return (was_active != *active);
20522 }
20523 /*----------------------------------------------------------------
20524  *
20525  * CHECKBOX
20526  *
20527  * --------------------------------------------------------------*/
20528 NK_API int
20529 nk_check_text(struct nk_context *ctx, const char *text, int len, int active)
20530 {
20531  struct nk_window *win;
20532  struct nk_panel *layout;
20533  const struct nk_input *in;
20534  const struct nk_style *style;
20535 
20536  struct nk_rect bounds;
20537  enum nk_widget_layout_states state;
20538 
20539  NK_ASSERT(ctx);
20540  NK_ASSERT(ctx->current);
20541  NK_ASSERT(ctx->current->layout);
20542  if (!ctx || !ctx->current || !ctx->current->layout)
20543  return active;
20544 
20545  win = ctx->current;
20546  style = &ctx->style;
20547  layout = win->layout;
20548 
20549  state = nk_widget(&bounds, ctx);
20550  if (!state) return active;
20551  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20552  nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &active,
20553  text, len, NK_TOGGLE_CHECK, &style->checkbox, in, style->font);
20554  return active;
20555 }
20556 NK_API unsigned int
20557 nk_check_flags_text(struct nk_context *ctx, const char *text, int len,
20558  unsigned int flags, unsigned int value)
20559 {
20560  int old_active;
20561  NK_ASSERT(ctx);
20562  NK_ASSERT(text);
20563  if (!ctx || !text) return flags;
20564  old_active = (int)((flags & value) & value);
20565  if (nk_check_text(ctx, text, len, old_active))
20566  flags |= value;
20567  else flags &= ~value;
20568  return flags;
20569 }
20570 NK_API int
20571 nk_checkbox_text(struct nk_context *ctx, const char *text, int len, int *active)
20572 {
20573  int old_val;
20574  NK_ASSERT(ctx);
20575  NK_ASSERT(text);
20576  NK_ASSERT(active);
20577  if (!ctx || !text || !active) return 0;
20578  old_val = *active;
20579  *active = nk_check_text(ctx, text, len, *active);
20580  return old_val != *active;
20581 }
20582 NK_API int
20583 nk_checkbox_flags_text(struct nk_context *ctx, const char *text, int len,
20584  unsigned int *flags, unsigned int value)
20585 {
20586  int active;
20587  NK_ASSERT(ctx);
20588  NK_ASSERT(text);
20589  NK_ASSERT(flags);
20590  if (!ctx || !text || !flags) return 0;
20591 
20592  active = (int)((*flags & value) & value);
20593  if (nk_checkbox_text(ctx, text, len, &active)) {
20594  if (active) *flags |= value;
20595  else *flags &= ~value;
20596  return 1;
20597  }
20598  return 0;
20599 }
20600 NK_API int nk_check_label(struct nk_context *ctx, const char *label, int active)
20601 {
20602  return nk_check_text(ctx, label, nk_strlen(label), active);
20603 }
20604 NK_API unsigned int nk_check_flags_label(struct nk_context *ctx, const char *label,
20605  unsigned int flags, unsigned int value)
20606 {
20607  return nk_check_flags_text(ctx, label, nk_strlen(label), flags, value);
20608 }
20609 NK_API int nk_checkbox_label(struct nk_context *ctx, const char *label, int *active)
20610 {
20611  return nk_checkbox_text(ctx, label, nk_strlen(label), active);
20612 }
20613 NK_API int nk_checkbox_flags_label(struct nk_context *ctx, const char *label,
20614  unsigned int *flags, unsigned int value)
20615 {
20616  return nk_checkbox_flags_text(ctx, label, nk_strlen(label), flags, value);
20617 }
20618 /*----------------------------------------------------------------
20619  *
20620  * OPTION
20621  *
20622  * --------------------------------------------------------------*/
20623 NK_API int
20624 nk_option_text(struct nk_context *ctx, const char *text, int len, int is_active)
20625 {
20626  struct nk_window *win;
20627  struct nk_panel *layout;
20628  const struct nk_input *in;
20629  const struct nk_style *style;
20630 
20631  struct nk_rect bounds;
20632  enum nk_widget_layout_states state;
20633 
20634  NK_ASSERT(ctx);
20635  NK_ASSERT(ctx->current);
20636  NK_ASSERT(ctx->current->layout);
20637  if (!ctx || !ctx->current || !ctx->current->layout)
20638  return is_active;
20639 
20640  win = ctx->current;
20641  style = &ctx->style;
20642  layout = win->layout;
20643 
20644  state = nk_widget(&bounds, ctx);
20645  if (!state) return (int)state;
20646  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20647  nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &is_active,
20648  text, len, NK_TOGGLE_OPTION, &style->option, in, style->font);
20649  return is_active;
20650 }
20651 NK_API int
20652 nk_radio_text(struct nk_context *ctx, const char *text, int len, int *active)
20653 {
20654  int old_value;
20655  NK_ASSERT(ctx);
20656  NK_ASSERT(text);
20657  NK_ASSERT(active);
20658  if (!ctx || !text || !active) return 0;
20659  old_value = *active;
20660  *active = nk_option_text(ctx, text, len, old_value);
20661  return old_value != *active;
20662 }
20663 NK_API int
20664 nk_option_label(struct nk_context *ctx, const char *label, int active)
20665 {
20666  return nk_option_text(ctx, label, nk_strlen(label), active);
20667 }
20668 NK_API int
20669 nk_radio_label(struct nk_context *ctx, const char *label, int *active)
20670 {
20671  return nk_radio_text(ctx, label, nk_strlen(label), active);
20672 }
20673 
20674 
20675 
20676 
20677 
20678 /* ===============================================================
20679  *
20680  * SELECTABLE
20681  *
20682  * ===============================================================*/
20683 NK_LIB void
20684 nk_draw_selectable(struct nk_command_buffer *out,
20685  nk_flags state, const struct nk_style_selectable *style, int active,
20686  const struct nk_rect *bounds,
20687  const struct nk_rect *icon, const struct nk_image *img, enum nk_symbol_type sym,
20688  const char *string, int len, nk_flags align, const struct nk_user_font *font)
20689 {
20690  const struct nk_style_item *background;
20691  struct nk_text text;
20692  text.padding = style->padding;
20693 
20694  /* select correct colors/images */
20695  if (!active) {
20696  if (state & NK_WIDGET_STATE_ACTIVED) {
20697  background = &style->pressed;
20698  text.text = style->text_pressed;
20699  } else if (state & NK_WIDGET_STATE_HOVER) {
20700  background = &style->hover;
20701  text.text = style->text_hover;
20702  } else {
20703  background = &style->normal;
20704  text.text = style->text_normal;
20705  }
20706  } else {
20707  if (state & NK_WIDGET_STATE_ACTIVED) {
20708  background = &style->pressed_active;
20709  text.text = style->text_pressed_active;
20710  } else if (state & NK_WIDGET_STATE_HOVER) {
20711  background = &style->hover_active;
20712  text.text = style->text_hover_active;
20713  } else {
20714  background = &style->normal_active;
20715  text.text = style->text_normal_active;
20716  }
20717  }
20718  /* draw selectable background and text */
20719  if (background->type == NK_STYLE_ITEM_IMAGE) {
20720  nk_draw_image(out, *bounds, &background->data.image, nk_white);
20721  text.background = nk_rgba(0,0,0,0);
20722  } else {
20723  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
20724  text.background = background->data.color;
20725  }
20726  if (icon) {
20727  if (img) nk_draw_image(out, *icon, img, nk_white);
20728  else nk_draw_symbol(out, sym, *icon, text.background, text.text, 1, font);
20729  }
20730  nk_widget_text(out, *bounds, string, len, &text, align, font);
20731 }
20732 NK_LIB int
20733 nk_do_selectable(nk_flags *state, struct nk_command_buffer *out,
20734  struct nk_rect bounds, const char *str, int len, nk_flags align, int *value,
20735  const struct nk_style_selectable *style, const struct nk_input *in,
20736  const struct nk_user_font *font)
20737 {
20738  int old_value;
20739  struct nk_rect touch;
20740 
20741  NK_ASSERT(state);
20742  NK_ASSERT(out);
20743  NK_ASSERT(str);
20744  NK_ASSERT(len);
20745  NK_ASSERT(value);
20746  NK_ASSERT(style);
20747  NK_ASSERT(font);
20748 
20749  if (!state || !out || !str || !len || !value || !style || !font) return 0;
20750  old_value = *value;
20751 
20752  /* remove padding */
20753  touch.x = bounds.x - style->touch_padding.x;
20754  touch.y = bounds.y - style->touch_padding.y;
20755  touch.w = bounds.w + style->touch_padding.x * 2;
20756  touch.h = bounds.h + style->touch_padding.y * 2;
20757 
20758  /* update button */
20759  if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
20760  *value = !(*value);
20761 
20762  /* draw selectable */
20763  if (style->draw_begin) style->draw_begin(out, style->userdata);
20764  nk_draw_selectable(out, *state, style, *value, &bounds, 0,0,NK_SYMBOL_NONE, str, len, align, font);
20765  if (style->draw_end) style->draw_end(out, style->userdata);
20766  return old_value != *value;
20767 }
20768 NK_LIB int
20769 nk_do_selectable_image(nk_flags *state, struct nk_command_buffer *out,
20770  struct nk_rect bounds, const char *str, int len, nk_flags align, int *value,
20771  const struct nk_image *img, const struct nk_style_selectable *style,
20772  const struct nk_input *in, const struct nk_user_font *font)
20773 {
20774  int old_value;
20775  struct nk_rect touch;
20776  struct nk_rect icon;
20777 
20778  NK_ASSERT(state);
20779  NK_ASSERT(out);
20780  NK_ASSERT(str);
20781  NK_ASSERT(len);
20782  NK_ASSERT(value);
20783  NK_ASSERT(style);
20784  NK_ASSERT(font);
20785 
20786  if (!state || !out || !str || !len || !value || !style || !font) return 0;
20787  old_value = *value;
20788 
20789  /* toggle behavior */
20790  touch.x = bounds.x - style->touch_padding.x;
20791  touch.y = bounds.y - style->touch_padding.y;
20792  touch.w = bounds.w + style->touch_padding.x * 2;
20793  touch.h = bounds.h + style->touch_padding.y * 2;
20794  if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
20795  *value = !(*value);
20796 
20797  icon.y = bounds.y + style->padding.y;
20798  icon.w = icon.h = bounds.h - 2 * style->padding.y;
20799  if (align & NK_TEXT_ALIGN_LEFT) {
20800  icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
20801  icon.x = NK_MAX(icon.x, 0);
20802  } else icon.x = bounds.x + 2 * style->padding.x;
20803 
20804  icon.x += style->image_padding.x;
20805  icon.y += style->image_padding.y;
20806  icon.w -= 2 * style->image_padding.x;
20807  icon.h -= 2 * style->image_padding.y;
20808 
20809  /* draw selectable */
20810  if (style->draw_begin) style->draw_begin(out, style->userdata);
20811  nk_draw_selectable(out, *state, style, *value, &bounds, &icon, img, NK_SYMBOL_NONE, str, len, align, font);
20812  if (style->draw_end) style->draw_end(out, style->userdata);
20813  return old_value != *value;
20814 }
20815 NK_LIB int
20816 nk_do_selectable_symbol(nk_flags *state, struct nk_command_buffer *out,
20817  struct nk_rect bounds, const char *str, int len, nk_flags align, int *value,
20818  enum nk_symbol_type sym, const struct nk_style_selectable *style,
20819  const struct nk_input *in, const struct nk_user_font *font)
20820 {
20821  int old_value;
20822  struct nk_rect touch;
20823  struct nk_rect icon;
20824 
20825  NK_ASSERT(state);
20826  NK_ASSERT(out);
20827  NK_ASSERT(str);
20828  NK_ASSERT(len);
20829  NK_ASSERT(value);
20830  NK_ASSERT(style);
20831  NK_ASSERT(font);
20832 
20833  if (!state || !out || !str || !len || !value || !style || !font) return 0;
20834  old_value = *value;
20835 
20836  /* toggle behavior */
20837  touch.x = bounds.x - style->touch_padding.x;
20838  touch.y = bounds.y - style->touch_padding.y;
20839  touch.w = bounds.w + style->touch_padding.x * 2;
20840  touch.h = bounds.h + style->touch_padding.y * 2;
20841  if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
20842  *value = !(*value);
20843 
20844  icon.y = bounds.y + style->padding.y;
20845  icon.w = icon.h = bounds.h - 2 * style->padding.y;
20846  if (align & NK_TEXT_ALIGN_LEFT) {
20847  icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
20848  icon.x = NK_MAX(icon.x, 0);
20849  } else icon.x = bounds.x + 2 * style->padding.x;
20850 
20851  icon.x += style->image_padding.x;
20852  icon.y += style->image_padding.y;
20853  icon.w -= 2 * style->image_padding.x;
20854  icon.h -= 2 * style->image_padding.y;
20855 
20856  /* draw selectable */
20857  if (style->draw_begin) style->draw_begin(out, style->userdata);
20858  nk_draw_selectable(out, *state, style, *value, &bounds, &icon, 0, sym, str, len, align, font);
20859  if (style->draw_end) style->draw_end(out, style->userdata);
20860  return old_value != *value;
20861 }
20862 
20863 NK_API int
20864 nk_selectable_text(struct nk_context *ctx, const char *str, int len,
20865  nk_flags align, int *value)
20866 {
20867  struct nk_window *win;
20868  struct nk_panel *layout;
20869  const struct nk_input *in;
20870  const struct nk_style *style;
20871 
20872  enum nk_widget_layout_states state;
20873  struct nk_rect bounds;
20874 
20875  NK_ASSERT(ctx);
20876  NK_ASSERT(value);
20877  NK_ASSERT(ctx->current);
20878  NK_ASSERT(ctx->current->layout);
20879  if (!ctx || !ctx->current || !ctx->current->layout || !value)
20880  return 0;
20881 
20882  win = ctx->current;
20883  layout = win->layout;
20884  style = &ctx->style;
20885 
20886  state = nk_widget(&bounds, ctx);
20887  if (!state) return 0;
20888  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20889  return nk_do_selectable(&ctx->last_widget_state, &win->buffer, bounds,
20890  str, len, align, value, &style->selectable, in, style->font);
20891 }
20892 NK_API int
20893 nk_selectable_image_text(struct nk_context *ctx, struct nk_image img,
20894  const char *str, int len, nk_flags align, int *value)
20895 {
20896  struct nk_window *win;
20897  struct nk_panel *layout;
20898  const struct nk_input *in;
20899  const struct nk_style *style;
20900 
20901  enum nk_widget_layout_states state;
20902  struct nk_rect bounds;
20903 
20904  NK_ASSERT(ctx);
20905  NK_ASSERT(value);
20906  NK_ASSERT(ctx->current);
20907  NK_ASSERT(ctx->current->layout);
20908  if (!ctx || !ctx->current || !ctx->current->layout || !value)
20909  return 0;
20910 
20911  win = ctx->current;
20912  layout = win->layout;
20913  style = &ctx->style;
20914 
20915  state = nk_widget(&bounds, ctx);
20916  if (!state) return 0;
20917  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20918  return nk_do_selectable_image(&ctx->last_widget_state, &win->buffer, bounds,
20919  str, len, align, value, &img, &style->selectable, in, style->font);
20920 }
20921 NK_API int
20923  const char *str, int len, nk_flags align, int *value)
20924 {
20925  struct nk_window *win;
20926  struct nk_panel *layout;
20927  const struct nk_input *in;
20928  const struct nk_style *style;
20929 
20930  enum nk_widget_layout_states state;
20931  struct nk_rect bounds;
20932 
20933  NK_ASSERT(ctx);
20934  NK_ASSERT(value);
20935  NK_ASSERT(ctx->current);
20936  NK_ASSERT(ctx->current->layout);
20937  if (!ctx || !ctx->current || !ctx->current->layout || !value)
20938  return 0;
20939 
20940  win = ctx->current;
20941  layout = win->layout;
20942  style = &ctx->style;
20943 
20944  state = nk_widget(&bounds, ctx);
20945  if (!state) return 0;
20946  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20947  return nk_do_selectable_symbol(&ctx->last_widget_state, &win->buffer, bounds,
20948  str, len, align, value, sym, &style->selectable, in, style->font);
20949 }
20950 NK_API int
20952  const char *title, nk_flags align, int *value)
20953 {
20954  return nk_selectable_symbol_text(ctx, sym, title, nk_strlen(title), align, value);
20955 }
20956 NK_API int nk_select_text(struct nk_context *ctx, const char *str, int len,
20957  nk_flags align, int value)
20958 {
20959  nk_selectable_text(ctx, str, len, align, &value);return value;
20960 }
20961 NK_API int nk_selectable_label(struct nk_context *ctx, const char *str, nk_flags align, int *value)
20962 {
20963  return nk_selectable_text(ctx, str, nk_strlen(str), align, value);
20964 }
20965 NK_API int nk_selectable_image_label(struct nk_context *ctx,struct nk_image img,
20966  const char *str, nk_flags align, int *value)
20967 {
20968  return nk_selectable_image_text(ctx, img, str, nk_strlen(str), align, value);
20969 }
20970 NK_API int nk_select_label(struct nk_context *ctx, const char *str, nk_flags align, int value)
20971 {
20972  nk_selectable_text(ctx, str, nk_strlen(str), align, &value);return value;
20973 }
20974 NK_API int nk_select_image_label(struct nk_context *ctx, struct nk_image img,
20975  const char *str, nk_flags align, int value)
20976 {
20977  nk_selectable_image_text(ctx, img, str, nk_strlen(str), align, &value);return value;
20978 }
20979 NK_API int nk_select_image_text(struct nk_context *ctx, struct nk_image img,
20980  const char *str, int len, nk_flags align, int value)
20981 {
20982  nk_selectable_image_text(ctx, img, str, len, align, &value);return value;
20983 }
20984 NK_API int
20986  const char *title, int title_len, nk_flags align, int value)
20987 {
20988  nk_selectable_symbol_text(ctx, sym, title, title_len, align, &value);return value;
20989 }
20990 NK_API int
20992  const char *title, nk_flags align, int value)
20993 {
20994  return nk_select_symbol_text(ctx, sym, title, nk_strlen(title), align, value);
20995 }
20996 
20997 
20998 
20999 
21000 
21001 /* ===============================================================
21002  *
21003  * SLIDER
21004  *
21005  * ===============================================================*/
21006 NK_LIB float
21007 nk_slider_behavior(nk_flags *state, struct nk_rect *logical_cursor,
21008  struct nk_rect *visual_cursor, struct nk_input *in,
21009  struct nk_rect bounds, float slider_min, float slider_max, float slider_value,
21010  float slider_step, float slider_steps)
21011 {
21012  int left_mouse_down;
21013  int left_mouse_click_in_cursor;
21014 
21015  /* check if visual cursor is being dragged */
21016  nk_widget_state_reset(state);
21017  left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
21018  left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in,
21019  NK_BUTTON_LEFT, *visual_cursor, nk_true);
21020 
21021  if (left_mouse_down && left_mouse_click_in_cursor) {
21022  float ratio = 0;
21023  const float d = in->mouse.pos.x - (visual_cursor->x+visual_cursor->w*0.5f);
21024  const float pxstep = bounds.w / slider_steps;
21025 
21026  /* only update value if the next slider step is reached */
21027  *state = NK_WIDGET_STATE_ACTIVE;
21028  if (NK_ABS(d) >= pxstep) {
21029  const float steps = (float)((int)(NK_ABS(d) / pxstep));
21030  slider_value += (d > 0) ? (slider_step*steps) : -(slider_step*steps);
21031  slider_value = NK_CLAMP(slider_min, slider_value, slider_max);
21032  ratio = (slider_value - slider_min)/slider_step;
21033  logical_cursor->x = bounds.x + (logical_cursor->w * ratio);
21034  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = logical_cursor->x;
21035  }
21036  }
21037 
21038  /* slider widget state */
21039  if (nk_input_is_mouse_hovering_rect(in, bounds))
21040  *state = NK_WIDGET_STATE_HOVERED;
21041  if (*state & NK_WIDGET_STATE_HOVER &&
21043  *state |= NK_WIDGET_STATE_ENTERED;
21044  else if (nk_input_is_mouse_prev_hovering_rect(in, bounds))
21045  *state |= NK_WIDGET_STATE_LEFT;
21046  return slider_value;
21047 }
21048 NK_LIB void
21049 nk_draw_slider(struct nk_command_buffer *out, nk_flags state,
21050  const struct nk_style_slider *style, const struct nk_rect *bounds,
21051  const struct nk_rect *visual_cursor, float min, float value, float max)
21052 {
21053  struct nk_rect fill;
21054  struct nk_rect bar;
21055  const struct nk_style_item *background;
21056 
21057  /* select correct slider images/colors */
21058  struct nk_color bar_color;
21059  const struct nk_style_item *cursor;
21060 
21061  NK_UNUSED(min);
21062  NK_UNUSED(max);
21063  NK_UNUSED(value);
21064 
21065  if (state & NK_WIDGET_STATE_ACTIVED) {
21066  background = &style->active;
21067  bar_color = style->bar_active;
21068  cursor = &style->cursor_active;
21069  } else if (state & NK_WIDGET_STATE_HOVER) {
21070  background = &style->hover;
21071  bar_color = style->bar_hover;
21072  cursor = &style->cursor_hover;
21073  } else {
21074  background = &style->normal;
21075  bar_color = style->bar_normal;
21076  cursor = &style->cursor_normal;
21077  }
21078  /* calculate slider background bar */
21079  bar.x = bounds->x;
21080  bar.y = (visual_cursor->y + visual_cursor->h/2) - bounds->h/12;
21081  bar.w = bounds->w;
21082  bar.h = bounds->h/6;
21083 
21084  /* filled background bar style */
21085  fill.w = (visual_cursor->x + (visual_cursor->w/2.0f)) - bar.x;
21086  fill.x = bar.x;
21087  fill.y = bar.y;
21088  fill.h = bar.h;
21089 
21090  /* draw background */
21091  if (background->type == NK_STYLE_ITEM_IMAGE) {
21092  nk_draw_image(out, *bounds, &background->data.image, nk_white);
21093  } else {
21094  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
21095  nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
21096  }
21097 
21098  /* draw slider bar */
21099  nk_fill_rect(out, bar, style->rounding, bar_color);
21100  nk_fill_rect(out, fill, style->rounding, style->bar_filled);
21101 
21102  /* draw cursor */
21103  if (cursor->type == NK_STYLE_ITEM_IMAGE)
21104  nk_draw_image(out, *visual_cursor, &cursor->data.image, nk_white);
21105  else nk_fill_circle(out, *visual_cursor, cursor->data.color);
21106 }
21107 NK_LIB float
21108 nk_do_slider(nk_flags *state,
21109  struct nk_command_buffer *out, struct nk_rect bounds,
21110  float min, float val, float max, float step,
21111  const struct nk_style_slider *style, struct nk_input *in,
21112  const struct nk_user_font *font)
21113 {
21114  float slider_range;
21115  float slider_min;
21116  float slider_max;
21117  float slider_value;
21118  float slider_steps;
21119  float cursor_offset;
21120 
21121  struct nk_rect visual_cursor;
21122  struct nk_rect logical_cursor;
21123 
21124  NK_ASSERT(style);
21125  NK_ASSERT(out);
21126  if (!out || !style)
21127  return 0;
21128 
21129  /* remove padding from slider bounds */
21130  bounds.x = bounds.x + style->padding.x;
21131  bounds.y = bounds.y + style->padding.y;
21132  bounds.h = NK_MAX(bounds.h, 2*style->padding.y);
21133  bounds.w = NK_MAX(bounds.w, 2*style->padding.x + style->cursor_size.x);
21134  bounds.w -= 2 * style->padding.x;
21135  bounds.h -= 2 * style->padding.y;
21136 
21137  /* optional buttons */
21138  if (style->show_buttons) {
21139  nk_flags ws;
21140  struct nk_rect button;
21141  button.y = bounds.y;
21142  button.w = bounds.h;
21143  button.h = bounds.h;
21144 
21145  /* decrement button */
21146  button.x = bounds.x;
21147  if (nk_do_button_symbol(&ws, out, button, style->dec_symbol, NK_BUTTON_DEFAULT,
21148  &style->dec_button, in, font))
21149  val -= step;
21150 
21151  /* increment button */
21152  button.x = (bounds.x + bounds.w) - button.w;
21153  if (nk_do_button_symbol(&ws, out, button, style->inc_symbol, NK_BUTTON_DEFAULT,
21154  &style->inc_button, in, font))
21155  val += step;
21156 
21157  bounds.x = bounds.x + button.w + style->spacing.x;
21158  bounds.w = bounds.w - (2*button.w + 2*style->spacing.x);
21159  }
21160 
21161  /* remove one cursor size to support visual cursor */
21162  bounds.x += style->cursor_size.x*0.5f;
21163  bounds.w -= style->cursor_size.x;
21164 
21165  /* make sure the provided values are correct */
21166  slider_max = NK_MAX(min, max);
21167  slider_min = NK_MIN(min, max);
21168  slider_value = NK_CLAMP(slider_min, val, slider_max);
21169  slider_range = slider_max - slider_min;
21170  slider_steps = slider_range / step;
21171  cursor_offset = (slider_value - slider_min) / step;
21172 
21173  /* calculate cursor
21174  Basically you have two cursors. One for visual representation and interaction
21175  and one for updating the actual cursor value. */
21176  logical_cursor.h = bounds.h;
21177  logical_cursor.w = bounds.w / slider_steps;
21178  logical_cursor.x = bounds.x + (logical_cursor.w * cursor_offset);
21179  logical_cursor.y = bounds.y;
21180 
21181  visual_cursor.h = style->cursor_size.y;
21182  visual_cursor.w = style->cursor_size.x;
21183  visual_cursor.y = (bounds.y + bounds.h*0.5f) - visual_cursor.h*0.5f;
21184  visual_cursor.x = logical_cursor.x - visual_cursor.w*0.5f;
21185 
21186  slider_value = nk_slider_behavior(state, &logical_cursor, &visual_cursor,
21187  in, bounds, slider_min, slider_max, slider_value, step, slider_steps);
21188  visual_cursor.x = logical_cursor.x - visual_cursor.w*0.5f;
21189 
21190  /* draw slider */
21191  if (style->draw_begin) style->draw_begin(out, style->userdata);
21192  nk_draw_slider(out, *state, style, &bounds, &visual_cursor, slider_min, slider_value, slider_max);
21193  if (style->draw_end) style->draw_end(out, style->userdata);
21194  return slider_value;
21195 }
21196 NK_API int
21197 nk_slider_float(struct nk_context *ctx, float min_value, float *value, float max_value,
21198  float value_step)
21199 {
21200  struct nk_window *win;
21201  struct nk_panel *layout;
21202  struct nk_input *in;
21203  const struct nk_style *style;
21204 
21205  int ret = 0;
21206  float old_value;
21207  struct nk_rect bounds;
21208  enum nk_widget_layout_states state;
21209 
21210  NK_ASSERT(ctx);
21211  NK_ASSERT(ctx->current);
21212  NK_ASSERT(ctx->current->layout);
21213  NK_ASSERT(value);
21214  if (!ctx || !ctx->current || !ctx->current->layout || !value)
21215  return ret;
21216 
21217  win = ctx->current;
21218  style = &ctx->style;
21219  layout = win->layout;
21220 
21221  state = nk_widget(&bounds, ctx);
21222  if (!state) return ret;
21223  in = (/*state == NK_WIDGET_ROM || */ layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
21224 
21225  old_value = *value;
21226  *value = nk_do_slider(&ctx->last_widget_state, &win->buffer, bounds, min_value,
21227  old_value, max_value, value_step, &style->slider, in, style->font);
21228  return (old_value > *value || old_value < *value);
21229 }
21230 NK_API float
21231 nk_slide_float(struct nk_context *ctx, float min, float val, float max, float step)
21232 {
21233  nk_slider_float(ctx, min, &val, max, step); return val;
21234 }
21235 NK_API int
21236 nk_slide_int(struct nk_context *ctx, int min, int val, int max, int step)
21237 {
21238  float value = (float)val;
21239  nk_slider_float(ctx, (float)min, &value, (float)max, (float)step);
21240  return (int)value;
21241 }
21242 NK_API int
21243 nk_slider_int(struct nk_context *ctx, int min, int *val, int max, int step)
21244 {
21245  int ret;
21246  float value = (float)*val;
21247  ret = nk_slider_float(ctx, (float)min, &value, (float)max, (float)step);
21248  *val = (int)value;
21249  return ret;
21250 }
21251 
21252 
21253 
21254 
21255 
21256 /* ===============================================================
21257  *
21258  * PROGRESS
21259  *
21260  * ===============================================================*/
21262 nk_progress_behavior(nk_flags *state, struct nk_input *in,
21263  struct nk_rect r, struct nk_rect cursor, nk_size max, nk_size value, int modifiable)
21264 {
21265  int left_mouse_down = 0;
21266  int left_mouse_click_in_cursor = 0;
21267 
21268  nk_widget_state_reset(state);
21269  if (!in || !modifiable) return value;
21270  left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
21271  left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in,
21272  NK_BUTTON_LEFT, cursor, nk_true);
21274  *state = NK_WIDGET_STATE_HOVERED;
21275 
21276  if (in && left_mouse_down && left_mouse_click_in_cursor) {
21277  if (left_mouse_down && left_mouse_click_in_cursor) {
21278  float ratio = NK_MAX(0, (float)(in->mouse.pos.x - cursor.x)) / (float)cursor.w;
21279  value = (nk_size)NK_CLAMP(0, (float)max * ratio, (float)max);
21280  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = cursor.x + cursor.w/2.0f;
21281  *state |= NK_WIDGET_STATE_ACTIVE;
21282  }
21283  }
21284  /* set progressbar widget state */
21286  *state |= NK_WIDGET_STATE_ENTERED;
21287  else if (nk_input_is_mouse_prev_hovering_rect(in, r))
21288  *state |= NK_WIDGET_STATE_LEFT;
21289  return value;
21290 }
21291 NK_LIB void
21292 nk_draw_progress(struct nk_command_buffer *out, nk_flags state,
21293  const struct nk_style_progress *style, const struct nk_rect *bounds,
21294  const struct nk_rect *scursor, nk_size value, nk_size max)
21295 {
21296  const struct nk_style_item *background;
21297  const struct nk_style_item *cursor;
21298 
21299  NK_UNUSED(max);
21300  NK_UNUSED(value);
21301 
21302  /* select correct colors/images to draw */
21303  if (state & NK_WIDGET_STATE_ACTIVED) {
21304  background = &style->active;
21305  cursor = &style->cursor_active;
21306  } else if (state & NK_WIDGET_STATE_HOVER){
21307  background = &style->hover;
21308  cursor = &style->cursor_hover;
21309  } else {
21310  background = &style->normal;
21311  cursor = &style->cursor_normal;
21312  }
21313 
21314  /* draw background */
21315  if (background->type == NK_STYLE_ITEM_COLOR) {
21316  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
21317  nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
21318  } else nk_draw_image(out, *bounds, &background->data.image, nk_white);
21319 
21320  /* draw cursor */
21321  if (cursor->type == NK_STYLE_ITEM_COLOR) {
21322  nk_fill_rect(out, *scursor, style->rounding, cursor->data.color);
21323  nk_stroke_rect(out, *scursor, style->rounding, style->border, style->border_color);
21324  } else nk_draw_image(out, *scursor, &cursor->data.image, nk_white);
21325 }
21327 nk_do_progress(nk_flags *state,
21328  struct nk_command_buffer *out, struct nk_rect bounds,
21329  nk_size value, nk_size max, int modifiable,
21330  const struct nk_style_progress *style, struct nk_input *in)
21331 {
21332  float prog_scale;
21333  nk_size prog_value;
21334  struct nk_rect cursor;
21335 
21336  NK_ASSERT(style);
21337  NK_ASSERT(out);
21338  if (!out || !style) return 0;
21339 
21340  /* calculate progressbar cursor */
21341  cursor.w = NK_MAX(bounds.w, 2 * style->padding.x + 2 * style->border);
21342  cursor.h = NK_MAX(bounds.h, 2 * style->padding.y + 2 * style->border);
21343  cursor = nk_pad_rect(bounds, nk_vec2(style->padding.x + style->border, style->padding.y + style->border));
21344  prog_scale = (float)value / (float)max;
21345 
21346  /* update progressbar */
21347  prog_value = NK_MIN(value, max);
21348  prog_value = nk_progress_behavior(state, in, bounds, cursor,max, prog_value, modifiable);
21349  cursor.w = cursor.w * prog_scale;
21350 
21351  /* draw progressbar */
21352  if (style->draw_begin) style->draw_begin(out, style->userdata);
21353  nk_draw_progress(out, *state, style, &bounds, &cursor, value, max);
21354  if (style->draw_end) style->draw_end(out, style->userdata);
21355  return prog_value;
21356 }
21357 NK_API int
21358 nk_progress(struct nk_context *ctx, nk_size *cur, nk_size max, int is_modifyable)
21359 {
21360  struct nk_window *win;
21361  struct nk_panel *layout;
21362  const struct nk_style *style;
21363  struct nk_input *in;
21364 
21365  struct nk_rect bounds;
21366  enum nk_widget_layout_states state;
21367  nk_size old_value;
21368 
21369  NK_ASSERT(ctx);
21370  NK_ASSERT(cur);
21371  NK_ASSERT(ctx->current);
21372  NK_ASSERT(ctx->current->layout);
21373  if (!ctx || !ctx->current || !ctx->current->layout || !cur)
21374  return 0;
21375 
21376  win = ctx->current;
21377  style = &ctx->style;
21378  layout = win->layout;
21379  state = nk_widget(&bounds, ctx);
21380  if (!state) return 0;
21381 
21382  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
21383  old_value = *cur;
21384  *cur = nk_do_progress(&ctx->last_widget_state, &win->buffer, bounds,
21385  *cur, max, is_modifyable, &style->progress, in);
21386  return (*cur != old_value);
21387 }
21389 nk_prog(struct nk_context *ctx, nk_size cur, nk_size max, int modifyable)
21390 {
21391  nk_progress(ctx, &cur, max, modifyable);
21392  return cur;
21393 }
21394 
21395 
21396 
21397 
21398 
21399 /* ===============================================================
21400  *
21401  * SCROLLBAR
21402  *
21403  * ===============================================================*/
21404 NK_LIB float
21405 nk_scrollbar_behavior(nk_flags *state, struct nk_input *in,
21406  int has_scrolling, const struct nk_rect *scroll,
21407  const struct nk_rect *cursor, const struct nk_rect *empty0,
21408  const struct nk_rect *empty1, float scroll_offset,
21409  float target, float scroll_step, enum nk_orientation o)
21410 {
21411  nk_flags ws = 0;
21412  int left_mouse_down;
21413  int left_mouse_clicked;
21414  int left_mouse_click_in_cursor;
21415  float scroll_delta;
21416 
21417  nk_widget_state_reset(state);
21418  if (!in) return scroll_offset;
21419 
21420  left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
21421  left_mouse_clicked = in->mouse.buttons[NK_BUTTON_LEFT].clicked;
21422  left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in,
21423  NK_BUTTON_LEFT, *cursor, nk_true);
21424  if (nk_input_is_mouse_hovering_rect(in, *scroll))
21425  *state = NK_WIDGET_STATE_HOVERED;
21426 
21427  scroll_delta = (o == NK_VERTICAL) ? in->mouse.scroll_delta.y: in->mouse.scroll_delta.x;
21428  if (left_mouse_down && left_mouse_click_in_cursor && !left_mouse_clicked) {
21429  /* update cursor by mouse dragging */
21430  float pixel, delta;
21431  *state = NK_WIDGET_STATE_ACTIVE;
21432  if (o == NK_VERTICAL) {
21433  float cursor_y;
21434  pixel = in->mouse.delta.y;
21435  delta = (pixel / scroll->h) * target;
21436  scroll_offset = NK_CLAMP(0, scroll_offset + delta, target - scroll->h);
21437  cursor_y = scroll->y + ((scroll_offset/target) * scroll->h);
21438  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = cursor_y + cursor->h/2.0f;
21439  } else {
21440  float cursor_x;
21441  pixel = in->mouse.delta.x;
21442  delta = (pixel / scroll->w) * target;
21443  scroll_offset = NK_CLAMP(0, scroll_offset + delta, target - scroll->w);
21444  cursor_x = scroll->x + ((scroll_offset/target) * scroll->w);
21445  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = cursor_x + cursor->w/2.0f;
21446  }
21447  } else if ((nk_input_is_key_pressed(in, NK_KEY_SCROLL_UP) && o == NK_VERTICAL && has_scrolling)||
21448  nk_button_behavior(&ws, *empty0, in, NK_BUTTON_DEFAULT)) {
21449  /* scroll page up by click on empty space or shortcut */
21450  if (o == NK_VERTICAL)
21451  scroll_offset = NK_MAX(0, scroll_offset - scroll->h);
21452  else scroll_offset = NK_MAX(0, scroll_offset - scroll->w);
21453  } else if ((nk_input_is_key_pressed(in, NK_KEY_SCROLL_DOWN) && o == NK_VERTICAL && has_scrolling) ||
21454  nk_button_behavior(&ws, *empty1, in, NK_BUTTON_DEFAULT)) {
21455  /* scroll page down by click on empty space or shortcut */
21456  if (o == NK_VERTICAL)
21457  scroll_offset = NK_MIN(scroll_offset + scroll->h, target - scroll->h);
21458  else scroll_offset = NK_MIN(scroll_offset + scroll->w, target - scroll->w);
21459  } else if (has_scrolling) {
21460  if ((scroll_delta < 0 || (scroll_delta > 0))) {
21461  /* update cursor by mouse scrolling */
21462  scroll_offset = scroll_offset + scroll_step * (-scroll_delta);
21463  if (o == NK_VERTICAL)
21464  scroll_offset = NK_CLAMP(0, scroll_offset, target - scroll->h);
21465  else scroll_offset = NK_CLAMP(0, scroll_offset, target - scroll->w);
21466  } else if (nk_input_is_key_pressed(in, NK_KEY_SCROLL_START)) {
21467  /* update cursor to the beginning */
21468  if (o == NK_VERTICAL) scroll_offset = 0;
21469  } else if (nk_input_is_key_pressed(in, NK_KEY_SCROLL_END)) {
21470  /* update cursor to the end */
21471  if (o == NK_VERTICAL) scroll_offset = target - scroll->h;
21472  }
21473  }
21474  if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, *scroll))
21475  *state |= NK_WIDGET_STATE_ENTERED;
21476  else if (nk_input_is_mouse_prev_hovering_rect(in, *scroll))
21477  *state |= NK_WIDGET_STATE_LEFT;
21478  return scroll_offset;
21479 }
21480 NK_LIB void
21481 nk_draw_scrollbar(struct nk_command_buffer *out, nk_flags state,
21482  const struct nk_style_scrollbar *style, const struct nk_rect *bounds,
21483  const struct nk_rect *scroll)
21484 {
21485  const struct nk_style_item *background;
21486  const struct nk_style_item *cursor;
21487 
21488  /* select correct colors/images to draw */
21489  if (state & NK_WIDGET_STATE_ACTIVED) {
21490  background = &style->active;
21491  cursor = &style->cursor_active;
21492  } else if (state & NK_WIDGET_STATE_HOVER) {
21493  background = &style->hover;
21494  cursor = &style->cursor_hover;
21495  } else {
21496  background = &style->normal;
21497  cursor = &style->cursor_normal;
21498  }
21499 
21500  /* draw background */
21501  if (background->type == NK_STYLE_ITEM_COLOR) {
21502  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
21503  nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
21504  } else {
21505  nk_draw_image(out, *bounds, &background->data.image, nk_white);
21506  }
21507 
21508  /* draw cursor */
21509  if (cursor->type == NK_STYLE_ITEM_COLOR) {
21510  nk_fill_rect(out, *scroll, style->rounding_cursor, cursor->data.color);
21511  nk_stroke_rect(out, *scroll, style->rounding_cursor, style->border_cursor, style->cursor_border_color);
21512  } else nk_draw_image(out, *scroll, &cursor->data.image, nk_white);
21513 }
21514 NK_LIB float
21515 nk_do_scrollbarv(nk_flags *state,
21516  struct nk_command_buffer *out, struct nk_rect scroll, int has_scrolling,
21517  float offset, float target, float step, float button_pixel_inc,
21518  const struct nk_style_scrollbar *style, struct nk_input *in,
21519  const struct nk_user_font *font)
21520 {
21521  struct nk_rect empty_north;
21522  struct nk_rect empty_south;
21523  struct nk_rect cursor;
21524 
21525  float scroll_step;
21526  float scroll_offset;
21527  float scroll_off;
21528  float scroll_ratio;
21529 
21530  NK_ASSERT(out);
21531  NK_ASSERT(style);
21532  NK_ASSERT(state);
21533  if (!out || !style) return 0;
21534 
21535  scroll.w = NK_MAX(scroll.w, 1);
21536  scroll.h = NK_MAX(scroll.h, 0);
21537  if (target <= scroll.h) return 0;
21538 
21539  /* optional scrollbar buttons */
21540  if (style->show_buttons) {
21541  nk_flags ws;
21542  float scroll_h;
21543  struct nk_rect button;
21544 
21545  button.x = scroll.x;
21546  button.w = scroll.w;
21547  button.h = scroll.w;
21548 
21549  scroll_h = NK_MAX(scroll.h - 2 * button.h,0);
21550  scroll_step = NK_MIN(step, button_pixel_inc);
21551 
21552  /* decrement button */
21553  button.y = scroll.y;
21554  if (nk_do_button_symbol(&ws, out, button, style->dec_symbol,
21555  NK_BUTTON_REPEATER, &style->dec_button, in, font))
21556  offset = offset - scroll_step;
21557 
21558  /* increment button */
21559  button.y = scroll.y + scroll.h - button.h;
21560  if (nk_do_button_symbol(&ws, out, button, style->inc_symbol,
21561  NK_BUTTON_REPEATER, &style->inc_button, in, font))
21562  offset = offset + scroll_step;
21563 
21564  scroll.y = scroll.y + button.h;
21565  scroll.h = scroll_h;
21566  }
21567 
21568  /* calculate scrollbar constants */
21569  scroll_step = NK_MIN(step, scroll.h);
21570  scroll_offset = NK_CLAMP(0, offset, target - scroll.h);
21571  scroll_ratio = scroll.h / target;
21572  scroll_off = scroll_offset / target;
21573 
21574  /* calculate scrollbar cursor bounds */
21575  cursor.h = NK_MAX((scroll_ratio * scroll.h) - (2*style->border + 2*style->padding.y), 0);
21576  cursor.y = scroll.y + (scroll_off * scroll.h) + style->border + style->padding.y;
21577  cursor.w = scroll.w - (2 * style->border + 2 * style->padding.x);
21578  cursor.x = scroll.x + style->border + style->padding.x;
21579 
21580  /* calculate empty space around cursor */
21581  empty_north.x = scroll.x;
21582  empty_north.y = scroll.y;
21583  empty_north.w = scroll.w;
21584  empty_north.h = NK_MAX(cursor.y - scroll.y, 0);
21585 
21586  empty_south.x = scroll.x;
21587  empty_south.y = cursor.y + cursor.h;
21588  empty_south.w = scroll.w;
21589  empty_south.h = NK_MAX((scroll.y + scroll.h) - (cursor.y + cursor.h), 0);
21590 
21591  /* update scrollbar */
21592  scroll_offset = nk_scrollbar_behavior(state, in, has_scrolling, &scroll, &cursor,
21593  &empty_north, &empty_south, scroll_offset, target, scroll_step, NK_VERTICAL);
21594  scroll_off = scroll_offset / target;
21595  cursor.y = scroll.y + (scroll_off * scroll.h) + style->border_cursor + style->padding.y;
21596 
21597  /* draw scrollbar */
21598  if (style->draw_begin) style->draw_begin(out, style->userdata);
21599  nk_draw_scrollbar(out, *state, style, &scroll, &cursor);
21600  if (style->draw_end) style->draw_end(out, style->userdata);
21601  return scroll_offset;
21602 }
21603 NK_LIB float
21604 nk_do_scrollbarh(nk_flags *state,
21605  struct nk_command_buffer *out, struct nk_rect scroll, int has_scrolling,
21606  float offset, float target, float step, float button_pixel_inc,
21607  const struct nk_style_scrollbar *style, struct nk_input *in,
21608  const struct nk_user_font *font)
21609 {
21610  struct nk_rect cursor;
21611  struct nk_rect empty_west;
21612  struct nk_rect empty_east;
21613 
21614  float scroll_step;
21615  float scroll_offset;
21616  float scroll_off;
21617  float scroll_ratio;
21618 
21619  NK_ASSERT(out);
21620  NK_ASSERT(style);
21621  if (!out || !style) return 0;
21622 
21623  /* scrollbar background */
21624  scroll.h = NK_MAX(scroll.h, 1);
21625  scroll.w = NK_MAX(scroll.w, 2 * scroll.h);
21626  if (target <= scroll.w) return 0;
21627 
21628  /* optional scrollbar buttons */
21629  if (style->show_buttons) {
21630  nk_flags ws;
21631  float scroll_w;
21632  struct nk_rect button;
21633  button.y = scroll.y;
21634  button.w = scroll.h;
21635  button.h = scroll.h;
21636 
21637  scroll_w = scroll.w - 2 * button.w;
21638  scroll_step = NK_MIN(step, button_pixel_inc);
21639 
21640  /* decrement button */
21641  button.x = scroll.x;
21642  if (nk_do_button_symbol(&ws, out, button, style->dec_symbol,
21643  NK_BUTTON_REPEATER, &style->dec_button, in, font))
21644  offset = offset - scroll_step;
21645 
21646  /* increment button */
21647  button.x = scroll.x + scroll.w - button.w;
21648  if (nk_do_button_symbol(&ws, out, button, style->inc_symbol,
21649  NK_BUTTON_REPEATER, &style->inc_button, in, font))
21650  offset = offset + scroll_step;
21651 
21652  scroll.x = scroll.x + button.w;
21653  scroll.w = scroll_w;
21654  }
21655 
21656  /* calculate scrollbar constants */
21657  scroll_step = NK_MIN(step, scroll.w);
21658  scroll_offset = NK_CLAMP(0, offset, target - scroll.w);
21659  scroll_ratio = scroll.w / target;
21660  scroll_off = scroll_offset / target;
21661 
21662  /* calculate cursor bounds */
21663  cursor.w = (scroll_ratio * scroll.w) - (2*style->border + 2*style->padding.x);
21664  cursor.x = scroll.x + (scroll_off * scroll.w) + style->border + style->padding.x;
21665  cursor.h = scroll.h - (2 * style->border + 2 * style->padding.y);
21666  cursor.y = scroll.y + style->border + style->padding.y;
21667 
21668  /* calculate empty space around cursor */
21669  empty_west.x = scroll.x;
21670  empty_west.y = scroll.y;
21671  empty_west.w = cursor.x - scroll.x;
21672  empty_west.h = scroll.h;
21673 
21674  empty_east.x = cursor.x + cursor.w;
21675  empty_east.y = scroll.y;
21676  empty_east.w = (scroll.x + scroll.w) - (cursor.x + cursor.w);
21677  empty_east.h = scroll.h;
21678 
21679  /* update scrollbar */
21680  scroll_offset = nk_scrollbar_behavior(state, in, has_scrolling, &scroll, &cursor,
21681  &empty_west, &empty_east, scroll_offset, target, scroll_step, NK_HORIZONTAL);
21682  scroll_off = scroll_offset / target;
21683  cursor.x = scroll.x + (scroll_off * scroll.w);
21684 
21685  /* draw scrollbar */
21686  if (style->draw_begin) style->draw_begin(out, style->userdata);
21687  nk_draw_scrollbar(out, *state, style, &scroll, &cursor);
21688  if (style->draw_end) style->draw_end(out, style->userdata);
21689  return scroll_offset;
21690 }
21691 
21692 
21693 
21694 
21695 
21696 /* ===============================================================
21697  *
21698  * TEXT EDITOR
21699  *
21700  * ===============================================================*/
21701 /* stb_textedit.h - v1.8 - public domain - Sean Barrett */
21702 struct nk_text_find {
21703  float x,y; /* position of n'th character */
21704  float height; /* height of line */
21705  int first_char, length; /* first char of row, and length */
21706  int prev_first; /*_ first char of previous row */
21707 };
21708 
21709 struct nk_text_edit_row {
21710  float x0,x1;
21711  /* starting x location, end x location (allows for align=right, etc) */
21712  float baseline_y_delta;
21713  /* position of baseline relative to previous row's baseline*/
21714  float ymin,ymax;
21715  /* height of row above and below baseline */
21716  int num_chars;
21717 };
21718 
21719 /* forward declarations */
21720 NK_INTERN void nk_textedit_makeundo_delete(struct nk_text_edit*, int, int);
21721 NK_INTERN void nk_textedit_makeundo_insert(struct nk_text_edit*, int, int);
21722 NK_INTERN void nk_textedit_makeundo_replace(struct nk_text_edit*, int, int, int);
21723 #define NK_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
21724 
21725 NK_INTERN float
21726 nk_textedit_get_width(const struct nk_text_edit *edit, int line_start, int char_id,
21727  const struct nk_user_font *font)
21728 {
21729  int len = 0;
21730  nk_rune unicode = 0;
21731  const char *str = nk_str_at_const(&edit->string, line_start + char_id, &unicode, &len);
21732  return font->width(font->userdata, font->height, str, len);
21733 }
21734 NK_INTERN void
21735 nk_textedit_layout_row(struct nk_text_edit_row *r, struct nk_text_edit *edit,
21736  int line_start_id, float row_height, const struct nk_user_font *font)
21737 {
21738  int l;
21739  int glyphs = 0;
21740  nk_rune unicode;
21741  const char *remaining;
21742  int len = nk_str_len_char(&edit->string);
21743  const char *end = nk_str_get_const(&edit->string) + len;
21744  const char *text = nk_str_at_const(&edit->string, line_start_id, &unicode, &l);
21745  const struct nk_vec2 size = nk_text_calculate_text_bounds(font,
21746  text, (int)(end - text), row_height, &remaining, 0, &glyphs, NK_STOP_ON_NEW_LINE);
21747 
21748  r->x0 = 0.0f;
21749  r->x1 = size.x;
21750  r->baseline_y_delta = size.y;
21751  r->ymin = 0.0f;
21752  r->ymax = size.y;
21753  r->num_chars = glyphs;
21754 }
21755 NK_INTERN int
21756 nk_textedit_locate_coord(struct nk_text_edit *edit, float x, float y,
21757  const struct nk_user_font *font, float row_height)
21758 {
21759  struct nk_text_edit_row r;
21760  int n = edit->string.len;
21761  float base_y = 0, prev_x;
21762  int i=0, k;
21763 
21764  r.x0 = r.x1 = 0;
21765  r.ymin = r.ymax = 0;
21766  r.num_chars = 0;
21767 
21768  /* search rows to find one that straddles 'y' */
21769  while (i < n) {
21770  nk_textedit_layout_row(&r, edit, i, row_height, font);
21771  if (r.num_chars <= 0)
21772  return n;
21773 
21774  if (i==0 && y < base_y + r.ymin)
21775  return 0;
21776 
21777  if (y < base_y + r.ymax)
21778  break;
21779 
21780  i += r.num_chars;
21781  base_y += r.baseline_y_delta;
21782  }
21783 
21784  /* below all text, return 'after' last character */
21785  if (i >= n)
21786  return n;
21787 
21788  /* check if it's before the beginning of the line */
21789  if (x < r.x0)
21790  return i;
21791 
21792  /* check if it's before the end of the line */
21793  if (x < r.x1) {
21794  /* search characters in row for one that straddles 'x' */
21795  k = i;
21796  prev_x = r.x0;
21797  for (i=0; i < r.num_chars; ++i) {
21798  float w = nk_textedit_get_width(edit, k, i, font);
21799  if (x < prev_x+w) {
21800  if (x < prev_x+w/2)
21801  return k+i;
21802  else return k+i+1;
21803  }
21804  prev_x += w;
21805  }
21806  /* shouldn't happen, but if it does, fall through to end-of-line case */
21807  }
21808 
21809  /* if the last character is a newline, return that.
21810  * otherwise return 'after' the last character */
21811  if (nk_str_rune_at(&edit->string, i+r.num_chars-1) == '\n')
21812  return i+r.num_chars-1;
21813  else return i+r.num_chars;
21814 }
21815 NK_LIB void
21816 nk_textedit_click(struct nk_text_edit *state, float x, float y,
21817  const struct nk_user_font *font, float row_height)
21818 {
21819  /* API click: on mouse down, move the cursor to the clicked location,
21820  * and reset the selection */
21821  state->cursor = nk_textedit_locate_coord(state, x, y, font, row_height);
21822  state->select_start = state->cursor;
21823  state->select_end = state->cursor;
21824  state->has_preferred_x = 0;
21825 }
21826 NK_LIB void
21827 nk_textedit_drag(struct nk_text_edit *state, float x, float y,
21828  const struct nk_user_font *font, float row_height)
21829 {
21830  /* API drag: on mouse drag, move the cursor and selection endpoint
21831  * to the clicked location */
21832  int p = nk_textedit_locate_coord(state, x, y, font, row_height);
21833  if (state->select_start == state->select_end)
21834  state->select_start = state->cursor;
21835  state->cursor = state->select_end = p;
21836 }
21837 NK_INTERN void
21838 nk_textedit_find_charpos(struct nk_text_find *find, struct nk_text_edit *state,
21839  int n, int single_line, const struct nk_user_font *font, float row_height)
21840 {
21841  /* find the x/y location of a character, and remember info about the previous
21842  * row in case we get a move-up event (for page up, we'll have to rescan) */
21843  struct nk_text_edit_row r;
21844  int prev_start = 0;
21845  int z = state->string.len;
21846  int i=0, first;
21847 
21848  nk_zero_struct(r);
21849  if (n == z) {
21850  /* if it's at the end, then find the last line -- simpler than trying to
21851  explicitly handle this case in the regular code */
21852  nk_textedit_layout_row(&r, state, 0, row_height, font);
21853  if (single_line) {
21854  find->first_char = 0;
21855  find->length = z;
21856  } else {
21857  while (i < z) {
21858  prev_start = i;
21859  i += r.num_chars;
21860  nk_textedit_layout_row(&r, state, i, row_height, font);
21861  }
21862 
21863  find->first_char = i;
21864  find->length = r.num_chars;
21865  }
21866  find->x = r.x1;
21867  find->y = r.ymin;
21868  find->height = r.ymax - r.ymin;
21869  find->prev_first = prev_start;
21870  return;
21871  }
21872 
21873  /* search rows to find the one that straddles character n */
21874  find->y = 0;
21875 
21876  for(;;) {
21877  nk_textedit_layout_row(&r, state, i, row_height, font);
21878  if (n < i + r.num_chars) break;
21879  prev_start = i;
21880  i += r.num_chars;
21881  find->y += r.baseline_y_delta;
21882  }
21883 
21884  find->first_char = first = i;
21885  find->length = r.num_chars;
21886  find->height = r.ymax - r.ymin;
21887  find->prev_first = prev_start;
21888 
21889  /* now scan to find xpos */
21890  find->x = r.x0;
21891  for (i=0; first+i < n; ++i)
21892  find->x += nk_textedit_get_width(state, first, i, font);
21893 }
21894 NK_INTERN void
21895 nk_textedit_clamp(struct nk_text_edit *state)
21896 {
21897  /* make the selection/cursor state valid if client altered the string */
21898  int n = state->string.len;
21899  if (NK_TEXT_HAS_SELECTION(state)) {
21900  if (state->select_start > n) state->select_start = n;
21901  if (state->select_end > n) state->select_end = n;
21902  /* if clamping forced them to be equal, move the cursor to match */
21903  if (state->select_start == state->select_end)
21904  state->cursor = state->select_start;
21905  }
21906  if (state->cursor > n) state->cursor = n;
21907 }
21908 NK_API void
21909 nk_textedit_delete(struct nk_text_edit *state, int where, int len)
21910 {
21911  /* delete characters while updating undo */
21912  nk_textedit_makeundo_delete(state, where, len);
21913  nk_str_delete_runes(&state->string, where, len);
21914  state->has_preferred_x = 0;
21915 }
21916 NK_API void
21918 {
21919  /* delete the section */
21920  nk_textedit_clamp(state);
21921  if (NK_TEXT_HAS_SELECTION(state)) {
21922  if (state->select_start < state->select_end) {
21923  nk_textedit_delete(state, state->select_start,
21924  state->select_end - state->select_start);
21925  state->select_end = state->cursor = state->select_start;
21926  } else {
21927  nk_textedit_delete(state, state->select_end,
21928  state->select_start - state->select_end);
21929  state->select_start = state->cursor = state->select_end;
21930  }
21931  state->has_preferred_x = 0;
21932  }
21933 }
21934 NK_INTERN void
21935 nk_textedit_sortselection(struct nk_text_edit *state)
21936 {
21937  /* canonicalize the selection so start <= end */
21938  if (state->select_end < state->select_start) {
21939  int temp = state->select_end;
21940  state->select_end = state->select_start;
21941  state->select_start = temp;
21942  }
21943 }
21944 NK_INTERN void
21945 nk_textedit_move_to_first(struct nk_text_edit *state)
21946 {
21947  /* move cursor to first character of selection */
21948  if (NK_TEXT_HAS_SELECTION(state)) {
21949  nk_textedit_sortselection(state);
21950  state->cursor = state->select_start;
21951  state->select_end = state->select_start;
21952  state->has_preferred_x = 0;
21953  }
21954 }
21955 NK_INTERN void
21956 nk_textedit_move_to_last(struct nk_text_edit *state)
21957 {
21958  /* move cursor to last character of selection */
21959  if (NK_TEXT_HAS_SELECTION(state)) {
21960  nk_textedit_sortselection(state);
21961  nk_textedit_clamp(state);
21962  state->cursor = state->select_end;
21963  state->select_start = state->select_end;
21964  state->has_preferred_x = 0;
21965  }
21966 }
21967 NK_INTERN int
21968 nk_is_word_boundary( struct nk_text_edit *state, int idx)
21969 {
21970  int len;
21971  nk_rune c;
21972  if (idx <= 0) return 1;
21973  if (!nk_str_at_rune(&state->string, idx, &c, &len)) return 1;
21974  return (c == ' ' || c == '\t' ||c == 0x3000 || c == ',' || c == ';' ||
21975  c == '(' || c == ')' || c == '{' || c == '}' || c == '[' || c == ']' ||
21976  c == '|');
21977 }
21978 NK_INTERN int
21979 nk_textedit_move_to_word_previous(struct nk_text_edit *state)
21980 {
21981  int c = state->cursor - 1;
21982  while( c >= 0 && !nk_is_word_boundary(state, c))
21983  --c;
21984 
21985  if( c < 0 )
21986  c = 0;
21987 
21988  return c;
21989 }
21990 NK_INTERN int
21991 nk_textedit_move_to_word_next(struct nk_text_edit *state)
21992 {
21993  const int len = state->string.len;
21994  int c = state->cursor+1;
21995  while( c < len && !nk_is_word_boundary(state, c))
21996  ++c;
21997 
21998  if( c > len )
21999  c = len;
22000 
22001  return c;
22002 }
22003 NK_INTERN void
22004 nk_textedit_prep_selection_at_cursor(struct nk_text_edit *state)
22005 {
22006  /* update selection and cursor to match each other */
22007  if (!NK_TEXT_HAS_SELECTION(state))
22008  state->select_start = state->select_end = state->cursor;
22009  else state->cursor = state->select_end;
22010 }
22011 NK_API int
22012 nk_textedit_cut(struct nk_text_edit *state)
22013 {
22014  /* API cut: delete selection */
22015  if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
22016  return 0;
22017  if (NK_TEXT_HAS_SELECTION(state)) {
22018  nk_textedit_delete_selection(state); /* implicitly clamps */
22019  state->has_preferred_x = 0;
22020  return 1;
22021  }
22022  return 0;
22023 }
22024 NK_API int
22025 nk_textedit_paste(struct nk_text_edit *state, char const *ctext, int len)
22026 {
22027  /* API paste: replace existing selection with passed-in text */
22028  int glyphs;
22029  const char *text = (const char *) ctext;
22030  if (state->mode == NK_TEXT_EDIT_MODE_VIEW) return 0;
22031 
22032  /* if there's a selection, the paste should delete it */
22033  nk_textedit_clamp(state);
22035 
22036  /* try to insert the characters */
22037  glyphs = nk_utf_len(ctext, len);
22038  if (nk_str_insert_text_char(&state->string, state->cursor, text, len)) {
22039  nk_textedit_makeundo_insert(state, state->cursor, glyphs);
22040  state->cursor += len;
22041  state->has_preferred_x = 0;
22042  return 1;
22043  }
22044  /* remove the undo since we didn't actually insert the characters */
22045  if (state->undo.undo_point)
22046  --state->undo.undo_point;
22047  return 0;
22048 }
22049 NK_API void
22050 nk_textedit_text(struct nk_text_edit *state, const char *text, int total_len)
22051 {
22052  nk_rune unicode;
22053  int glyph_len;
22054  int text_len = 0;
22055 
22056  NK_ASSERT(state);
22057  NK_ASSERT(text);
22058  if (!text || !total_len || state->mode == NK_TEXT_EDIT_MODE_VIEW) return;
22059 
22060  glyph_len = nk_utf_decode(text, &unicode, total_len);
22061  while ((text_len < total_len) && glyph_len)
22062  {
22063  /* don't insert a backward delete, just process the event */
22064  if (unicode == 127) goto next;
22065  /* can't add newline in single-line mode */
22066  if (unicode == '\n' && state->single_line) goto next;
22067  /* filter incoming text */
22068  if (state->filter && !state->filter(state, unicode)) goto next;
22069 
22070  if (!NK_TEXT_HAS_SELECTION(state) &&
22071  state->cursor < state->string.len)
22072  {
22073  if (state->mode == NK_TEXT_EDIT_MODE_REPLACE) {
22074  nk_textedit_makeundo_replace(state, state->cursor, 1, 1);
22075  nk_str_delete_runes(&state->string, state->cursor, 1);
22076  }
22077  if (nk_str_insert_text_utf8(&state->string, state->cursor,
22078  text+text_len, 1))
22079  {
22080  ++state->cursor;
22081  state->has_preferred_x = 0;
22082  }
22083  } else {
22084  nk_textedit_delete_selection(state); /* implicitly clamps */
22085  if (nk_str_insert_text_utf8(&state->string, state->cursor,
22086  text+text_len, 1))
22087  {
22088  nk_textedit_makeundo_insert(state, state->cursor, 1);
22089  ++state->cursor;
22090  state->has_preferred_x = 0;
22091  }
22092  }
22093  next:
22094  text_len += glyph_len;
22095  glyph_len = nk_utf_decode(text + text_len, &unicode, total_len-text_len);
22096  }
22097 }
22098 NK_LIB void
22099 nk_textedit_key(struct nk_text_edit *state, enum nk_keys key, int shift_mod,
22100  const struct nk_user_font *font, float row_height)
22101 {
22102 retry:
22103  switch (key)
22104  {
22105  case NK_KEY_NONE:
22106  case NK_KEY_CTRL:
22107  case NK_KEY_ENTER:
22108  case NK_KEY_SHIFT:
22109  case NK_KEY_TAB:
22110  case NK_KEY_COPY:
22111  case NK_KEY_CUT:
22112  case NK_KEY_PASTE:
22113  case NK_KEY_MAX:
22114  default: break;
22115  case NK_KEY_TEXT_UNDO:
22116  nk_textedit_undo(state);
22117  state->has_preferred_x = 0;
22118  break;
22119 
22120  case NK_KEY_TEXT_REDO:
22121  nk_textedit_redo(state);
22122  state->has_preferred_x = 0;
22123  break;
22124 
22126  nk_textedit_select_all(state);
22127  state->has_preferred_x = 0;
22128  break;
22129 
22131  if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
22132  state->mode = NK_TEXT_EDIT_MODE_INSERT;
22133  break;
22135  if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
22137  break;
22139  if (state->mode == NK_TEXT_EDIT_MODE_INSERT ||
22140  state->mode == NK_TEXT_EDIT_MODE_REPLACE)
22141  state->mode = NK_TEXT_EDIT_MODE_VIEW;
22142  break;
22143 
22144  case NK_KEY_LEFT:
22145  if (shift_mod) {
22146  nk_textedit_clamp(state);
22147  nk_textedit_prep_selection_at_cursor(state);
22148  /* move selection left */
22149  if (state->select_end > 0)
22150  --state->select_end;
22151  state->cursor = state->select_end;
22152  state->has_preferred_x = 0;
22153  } else {
22154  /* if currently there's a selection,
22155  * move cursor to start of selection */
22156  if (NK_TEXT_HAS_SELECTION(state))
22157  nk_textedit_move_to_first(state);
22158  else if (state->cursor > 0)
22159  --state->cursor;
22160  state->has_preferred_x = 0;
22161  } break;
22162 
22163  case NK_KEY_RIGHT:
22164  if (shift_mod) {
22165  nk_textedit_prep_selection_at_cursor(state);
22166  /* move selection right */
22167  ++state->select_end;
22168  nk_textedit_clamp(state);
22169  state->cursor = state->select_end;
22170  state->has_preferred_x = 0;
22171  } else {
22172  /* if currently there's a selection,
22173  * move cursor to end of selection */
22174  if (NK_TEXT_HAS_SELECTION(state))
22175  nk_textedit_move_to_last(state);
22176  else ++state->cursor;
22177  nk_textedit_clamp(state);
22178  state->has_preferred_x = 0;
22179  } break;
22180 
22181  case NK_KEY_TEXT_WORD_LEFT:
22182  if (shift_mod) {
22183  if( !NK_TEXT_HAS_SELECTION( state ) )
22184  nk_textedit_prep_selection_at_cursor(state);
22185  state->cursor = nk_textedit_move_to_word_previous(state);
22186  state->select_end = state->cursor;
22187  nk_textedit_clamp(state );
22188  } else {
22189  if (NK_TEXT_HAS_SELECTION(state))
22190  nk_textedit_move_to_first(state);
22191  else {
22192  state->cursor = nk_textedit_move_to_word_previous(state);
22193  nk_textedit_clamp(state );
22194  }
22195  } break;
22196 
22198  if (shift_mod) {
22199  if( !NK_TEXT_HAS_SELECTION( state ) )
22200  nk_textedit_prep_selection_at_cursor(state);
22201  state->cursor = nk_textedit_move_to_word_next(state);
22202  state->select_end = state->cursor;
22203  nk_textedit_clamp(state);
22204  } else {
22205  if (NK_TEXT_HAS_SELECTION(state))
22206  nk_textedit_move_to_last(state);
22207  else {
22208  state->cursor = nk_textedit_move_to_word_next(state);
22209  nk_textedit_clamp(state );
22210  }
22211  } break;
22212 
22213  case NK_KEY_DOWN: {
22214  struct nk_text_find find;
22215  struct nk_text_edit_row row;
22216  int i, sel = shift_mod;
22217 
22218  if (state->single_line) {
22219  /* on windows, up&down in single-line behave like left&right */
22220  key = NK_KEY_RIGHT;
22221  goto retry;
22222  }
22223 
22224  if (sel)
22225  nk_textedit_prep_selection_at_cursor(state);
22226  else if (NK_TEXT_HAS_SELECTION(state))
22227  nk_textedit_move_to_last(state);
22228 
22229  /* compute current position of cursor point */
22230  nk_textedit_clamp(state);
22231  nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
22232  font, row_height);
22233 
22234  /* now find character position down a row */
22235  if (find.length)
22236  {
22237  float x;
22238  float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
22239  int start = find.first_char + find.length;
22240 
22241  state->cursor = start;
22242  nk_textedit_layout_row(&row, state, state->cursor, row_height, font);
22243  x = row.x0;
22244 
22245  for (i=0; i < row.num_chars && x < row.x1; ++i) {
22246  float dx = nk_textedit_get_width(state, start, i, font);
22247  x += dx;
22248  if (x > goal_x)
22249  break;
22250  ++state->cursor;
22251  }
22252  nk_textedit_clamp(state);
22253 
22254  state->has_preferred_x = 1;
22255  state->preferred_x = goal_x;
22256  if (sel)
22257  state->select_end = state->cursor;
22258  }
22259  } break;
22260 
22261  case NK_KEY_UP: {
22262  struct nk_text_find find;
22263  struct nk_text_edit_row row;
22264  int i, sel = shift_mod;
22265 
22266  if (state->single_line) {
22267  /* on windows, up&down become left&right */
22268  key = NK_KEY_LEFT;
22269  goto retry;
22270  }
22271 
22272  if (sel)
22273  nk_textedit_prep_selection_at_cursor(state);
22274  else if (NK_TEXT_HAS_SELECTION(state))
22275  nk_textedit_move_to_first(state);
22276 
22277  /* compute current position of cursor point */
22278  nk_textedit_clamp(state);
22279  nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
22280  font, row_height);
22281 
22282  /* can only go up if there's a previous row */
22283  if (find.prev_first != find.first_char) {
22284  /* now find character position up a row */
22285  float x;
22286  float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
22287 
22288  state->cursor = find.prev_first;
22289  nk_textedit_layout_row(&row, state, state->cursor, row_height, font);
22290  x = row.x0;
22291 
22292  for (i=0; i < row.num_chars && x < row.x1; ++i) {
22293  float dx = nk_textedit_get_width(state, find.prev_first, i, font);
22294  x += dx;
22295  if (x > goal_x)
22296  break;
22297  ++state->cursor;
22298  }
22299  nk_textedit_clamp(state);
22300 
22301  state->has_preferred_x = 1;
22302  state->preferred_x = goal_x;
22303  if (sel) state->select_end = state->cursor;
22304  }
22305  } break;
22306 
22307  case NK_KEY_DEL:
22308  if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
22309  break;
22310  if (NK_TEXT_HAS_SELECTION(state))
22312  else {
22313  int n = state->string.len;
22314  if (state->cursor < n)
22315  nk_textedit_delete(state, state->cursor, 1);
22316  }
22317  state->has_preferred_x = 0;
22318  break;
22319 
22320  case NK_KEY_BACKSPACE:
22321  if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
22322  break;
22323  if (NK_TEXT_HAS_SELECTION(state))
22325  else {
22326  nk_textedit_clamp(state);
22327  if (state->cursor > 0) {
22328  nk_textedit_delete(state, state->cursor-1, 1);
22329  --state->cursor;
22330  }
22331  }
22332  state->has_preferred_x = 0;
22333  break;
22334 
22335  case NK_KEY_TEXT_START:
22336  if (shift_mod) {
22337  nk_textedit_prep_selection_at_cursor(state);
22338  state->cursor = state->select_end = 0;
22339  state->has_preferred_x = 0;
22340  } else {
22341  state->cursor = state->select_start = state->select_end = 0;
22342  state->has_preferred_x = 0;
22343  }
22344  break;
22345 
22346  case NK_KEY_TEXT_END:
22347  if (shift_mod) {
22348  nk_textedit_prep_selection_at_cursor(state);
22349  state->cursor = state->select_end = state->string.len;
22350  state->has_preferred_x = 0;
22351  } else {
22352  state->cursor = state->string.len;
22353  state->select_start = state->select_end = 0;
22354  state->has_preferred_x = 0;
22355  }
22356  break;
22357 
22358  case NK_KEY_TEXT_LINE_START: {
22359  if (shift_mod) {
22360  struct nk_text_find find;
22361  nk_textedit_clamp(state);
22362  nk_textedit_prep_selection_at_cursor(state);
22363  if (state->string.len && state->cursor == state->string.len)
22364  --state->cursor;
22365  nk_textedit_find_charpos(&find, state,state->cursor, state->single_line,
22366  font, row_height);
22367  state->cursor = state->select_end = find.first_char;
22368  state->has_preferred_x = 0;
22369  } else {
22370  struct nk_text_find find;
22371  if (state->string.len && state->cursor == state->string.len)
22372  --state->cursor;
22373  nk_textedit_clamp(state);
22374  nk_textedit_move_to_first(state);
22375  nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
22376  font, row_height);
22377  state->cursor = find.first_char;
22378  state->has_preferred_x = 0;
22379  }
22380  } break;
22381 
22382  case NK_KEY_TEXT_LINE_END: {
22383  if (shift_mod) {
22384  struct nk_text_find find;
22385  nk_textedit_clamp(state);
22386  nk_textedit_prep_selection_at_cursor(state);
22387  nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
22388  font, row_height);
22389  state->has_preferred_x = 0;
22390  state->cursor = find.first_char + find.length;
22391  if (find.length > 0 && nk_str_rune_at(&state->string, state->cursor-1) == '\n')
22392  --state->cursor;
22393  state->select_end = state->cursor;
22394  } else {
22395  struct nk_text_find find;
22396  nk_textedit_clamp(state);
22397  nk_textedit_move_to_first(state);
22398  nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
22399  font, row_height);
22400 
22401  state->has_preferred_x = 0;
22402  state->cursor = find.first_char + find.length;
22403  if (find.length > 0 && nk_str_rune_at(&state->string, state->cursor-1) == '\n')
22404  --state->cursor;
22405  }} break;
22406  }
22407 }
22408 NK_INTERN void
22409 nk_textedit_flush_redo(struct nk_text_undo_state *state)
22410 {
22413 }
22414 NK_INTERN void
22415 nk_textedit_discard_undo(struct nk_text_undo_state *state)
22416 {
22417  /* discard the oldest entry in the undo list */
22418  if (state->undo_point > 0) {
22419  /* if the 0th undo state has characters, clean those up */
22420  if (state->undo_rec[0].char_storage >= 0) {
22421  int n = state->undo_rec[0].insert_length, i;
22422  /* delete n characters from all other records */
22423  state->undo_char_point = (short)(state->undo_char_point - n);
22424  NK_MEMCPY(state->undo_char, state->undo_char + n,
22425  (nk_size)state->undo_char_point*sizeof(nk_rune));
22426  for (i=0; i < state->undo_point; ++i) {
22427  if (state->undo_rec[i].char_storage >= 0)
22428  state->undo_rec[i].char_storage = (short)
22429  (state->undo_rec[i].char_storage - n);
22430  }
22431  }
22432  --state->undo_point;
22433  NK_MEMCPY(state->undo_rec, state->undo_rec+1,
22434  (nk_size)((nk_size)state->undo_point * sizeof(state->undo_rec[0])));
22435  }
22436 }
22437 NK_INTERN void
22438 nk_textedit_discard_redo(struct nk_text_undo_state *state)
22439 {
22440 /* discard the oldest entry in the redo list--it's bad if this
22441  ever happens, but because undo & redo have to store the actual
22442  characters in different cases, the redo character buffer can
22443  fill up even though the undo buffer didn't */
22444  nk_size num;
22445  int k = NK_TEXTEDIT_UNDOSTATECOUNT-1;
22446  if (state->redo_point <= k) {
22447  /* if the k'th undo state has characters, clean those up */
22448  if (state->undo_rec[k].char_storage >= 0) {
22449  int n = state->undo_rec[k].insert_length, i;
22450  /* delete n characters from all other records */
22451  state->redo_char_point = (short)(state->redo_char_point + n);
22453  NK_MEMCPY(state->undo_char + state->redo_char_point,
22454  state->undo_char + state->redo_char_point-n, num * sizeof(char));
22455  for (i = state->redo_point; i < k; ++i) {
22456  if (state->undo_rec[i].char_storage >= 0) {
22457  state->undo_rec[i].char_storage = (short)
22458  (state->undo_rec[i].char_storage + n);
22459  }
22460  }
22461  }
22462  ++state->redo_point;
22463  num = (nk_size)(NK_TEXTEDIT_UNDOSTATECOUNT - state->redo_point);
22464  if (num) NK_MEMCPY(state->undo_rec + state->redo_point-1,
22465  state->undo_rec + state->redo_point, num * sizeof(state->undo_rec[0]));
22466  }
22467 }
22469 nk_textedit_create_undo_record(struct nk_text_undo_state *state, int numchars)
22470 {
22471  /* any time we create a new undo record, we discard redo*/
22472  nk_textedit_flush_redo(state);
22473 
22474  /* if we have no free records, we have to make room,
22475  * by sliding the existing records down */
22476  if (state->undo_point == NK_TEXTEDIT_UNDOSTATECOUNT)
22477  nk_textedit_discard_undo(state);
22478 
22479  /* if the characters to store won't possibly fit in the buffer,
22480  * we can't undo */
22481  if (numchars > NK_TEXTEDIT_UNDOCHARCOUNT) {
22482  state->undo_point = 0;
22483  state->undo_char_point = 0;
22484  return 0;
22485  }
22486 
22487  /* if we don't have enough free characters in the buffer,
22488  * we have to make room */
22489  while (state->undo_char_point + numchars > NK_TEXTEDIT_UNDOCHARCOUNT)
22490  nk_textedit_discard_undo(state);
22491  return &state->undo_rec[state->undo_point++];
22492 }
22494 nk_textedit_createundo(struct nk_text_undo_state *state, int pos,
22495  int insert_len, int delete_len)
22496 {
22497  struct nk_text_undo_record *r = nk_textedit_create_undo_record(state, insert_len);
22498  if (r == 0)
22499  return 0;
22500 
22501  r->where = pos;
22502  r->insert_length = (short) insert_len;
22503  r->delete_length = (short) delete_len;
22504 
22505  if (insert_len == 0) {
22506  r->char_storage = -1;
22507  return 0;
22508  } else {
22509  r->char_storage = state->undo_char_point;
22510  state->undo_char_point = (short)(state->undo_char_point + insert_len);
22511  return &state->undo_char[r->char_storage];
22512  }
22513 }
22514 NK_API void
22515 nk_textedit_undo(struct nk_text_edit *state)
22516 {
22517  struct nk_text_undo_state *s = &state->undo;
22518  struct nk_text_undo_record u, *r;
22519  if (s->undo_point == 0)
22520  return;
22521 
22522  /* we need to do two things: apply the undo record, and create a redo record */
22523  u = s->undo_rec[s->undo_point-1];
22524  r = &s->undo_rec[s->redo_point-1];
22525  r->char_storage = -1;
22526 
22527  r->insert_length = u.delete_length;
22528  r->delete_length = u.insert_length;
22529  r->where = u.where;
22530 
22531  if (u.delete_length)
22532  {
22533  /* if the undo record says to delete characters, then the redo record will
22534  need to re-insert the characters that get deleted, so we need to store
22535  them.
22536  there are three cases:
22537  - there's enough room to store the characters
22538  - characters stored for *redoing* don't leave room for redo
22539  - characters stored for *undoing* don't leave room for redo
22540  if the last is true, we have to bail */
22541  if (s->undo_char_point + u.delete_length >= NK_TEXTEDIT_UNDOCHARCOUNT) {
22542  /* the undo records take up too much character space; there's no space
22543  * to store the redo characters */
22544  r->insert_length = 0;
22545  } else {
22546  int i;
22547  /* there's definitely room to store the characters eventually */
22548  while (s->undo_char_point + u.delete_length > s->redo_char_point) {
22549  /* there's currently not enough room, so discard a redo record */
22550  nk_textedit_discard_redo(s);
22551  /* should never happen: */
22553  return;
22554  }
22555 
22556  r = &s->undo_rec[s->redo_point-1];
22557  r->char_storage = (short)(s->redo_char_point - u.delete_length);
22558  s->redo_char_point = (short)(s->redo_char_point - u.delete_length);
22559 
22560  /* now save the characters */
22561  for (i=0; i < u.delete_length; ++i)
22562  s->undo_char[r->char_storage + i] =
22563  nk_str_rune_at(&state->string, u.where + i);
22564  }
22565  /* now we can carry out the deletion */
22566  nk_str_delete_runes(&state->string, u.where, u.delete_length);
22567  }
22568 
22569  /* check type of recorded action: */
22570  if (u.insert_length) {
22571  /* easy case: was a deletion, so we need to insert n characters */
22572  nk_str_insert_text_runes(&state->string, u.where,
22573  &s->undo_char[u.char_storage], u.insert_length);
22574  s->undo_char_point = (short)(s->undo_char_point - u.insert_length);
22575  }
22576  state->cursor = (short)(u.where + u.insert_length);
22577 
22578  s->undo_point--;
22579  s->redo_point--;
22580 }
22581 NK_API void
22582 nk_textedit_redo(struct nk_text_edit *state)
22583 {
22584  struct nk_text_undo_state *s = &state->undo;
22585  struct nk_text_undo_record *u, r;
22587  return;
22588 
22589  /* we need to do two things: apply the redo record, and create an undo record */
22590  u = &s->undo_rec[s->undo_point];
22591  r = s->undo_rec[s->redo_point];
22592 
22593  /* we KNOW there must be room for the undo record, because the redo record
22594  was derived from an undo record */
22597  u->where = r.where;
22598  u->char_storage = -1;
22599 
22600  if (r.delete_length) {
22601  /* the redo record requires us to delete characters, so the undo record
22602  needs to store the characters */
22603  if (s->undo_char_point + u->insert_length > s->redo_char_point) {
22604  u->insert_length = 0;
22605  u->delete_length = 0;
22606  } else {
22607  int i;
22608  u->char_storage = s->undo_char_point;
22609  s->undo_char_point = (short)(s->undo_char_point + u->insert_length);
22610 
22611  /* now save the characters */
22612  for (i=0; i < u->insert_length; ++i) {
22613  s->undo_char[u->char_storage + i] =
22614  nk_str_rune_at(&state->string, u->where + i);
22615  }
22616  }
22618  }
22619 
22620  if (r.insert_length) {
22621  /* easy case: need to insert n characters */
22624  }
22625  state->cursor = r.where + r.insert_length;
22626 
22627  s->undo_point++;
22628  s->redo_point++;
22629 }
22630 NK_INTERN void
22631 nk_textedit_makeundo_insert(struct nk_text_edit *state, int where, int length)
22632 {
22633  nk_textedit_createundo(&state->undo, where, 0, length);
22634 }
22635 NK_INTERN void
22636 nk_textedit_makeundo_delete(struct nk_text_edit *state, int where, int length)
22637 {
22638  int i;
22639  nk_rune *p = nk_textedit_createundo(&state->undo, where, length, 0);
22640  if (p) {
22641  for (i=0; i < length; ++i)
22642  p[i] = nk_str_rune_at(&state->string, where+i);
22643  }
22644 }
22645 NK_INTERN void
22646 nk_textedit_makeundo_replace(struct nk_text_edit *state, int where,
22647  int old_length, int new_length)
22648 {
22649  int i;
22650  nk_rune *p = nk_textedit_createundo(&state->undo, where, old_length, new_length);
22651  if (p) {
22652  for (i=0; i < old_length; ++i)
22653  p[i] = nk_str_rune_at(&state->string, where+i);
22654  }
22655 }
22656 NK_LIB void
22657 nk_textedit_clear_state(struct nk_text_edit *state, enum nk_text_edit_type type,
22658  nk_plugin_filter filter)
22659 {
22660  /* reset the state to default */
22661  state->undo.undo_point = 0;
22662  state->undo.undo_char_point = 0;
22665  state->select_end = state->select_start = 0;
22666  state->cursor = 0;
22667  state->has_preferred_x = 0;
22668  state->preferred_x = 0;
22669  state->cursor_at_end_of_line = 0;
22670  state->initialized = 1;
22671  state->single_line = (unsigned char)(type == NK_TEXT_EDIT_SINGLE_LINE);
22672  state->mode = NK_TEXT_EDIT_MODE_VIEW;
22673  state->filter = filter;
22674  state->scrollbar = nk_vec2(0,0);
22675 }
22676 NK_API void
22677 nk_textedit_init_fixed(struct nk_text_edit *state, void *memory, nk_size size)
22678 {
22679  NK_ASSERT(state);
22680  NK_ASSERT(memory);
22681  if (!state || !memory || !size) return;
22682  NK_MEMSET(state, 0, sizeof(struct nk_text_edit));
22683  nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
22684  nk_str_init_fixed(&state->string, memory, size);
22685 }
22686 NK_API void
22687 nk_textedit_init(struct nk_text_edit *state, struct nk_allocator *alloc, nk_size size)
22688 {
22689  NK_ASSERT(state);
22690  NK_ASSERT(alloc);
22691  if (!state || !alloc) return;
22692  NK_MEMSET(state, 0, sizeof(struct nk_text_edit));
22693  nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
22694  nk_str_init(&state->string, alloc, size);
22695 }
22696 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
22697 NK_API void
22698 nk_textedit_init_default(struct nk_text_edit *state)
22699 {
22700  NK_ASSERT(state);
22701  if (!state) return;
22702  NK_MEMSET(state, 0, sizeof(struct nk_text_edit));
22703  nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
22704  nk_str_init_default(&state->string);
22705 }
22706 #endif
22707 NK_API void
22708 nk_textedit_select_all(struct nk_text_edit *state)
22709 {
22710  NK_ASSERT(state);
22711  state->select_start = 0;
22712  state->select_end = state->string.len;
22713 }
22714 NK_API void
22715 nk_textedit_free(struct nk_text_edit *state)
22716 {
22717  NK_ASSERT(state);
22718  if (!state) return;
22719  nk_str_free(&state->string);
22720 }
22721 
22722 
22723 
22724 
22725 
22726 /* ===============================================================
22727  *
22728  * FILTER
22729  *
22730  * ===============================================================*/
22731 NK_API int
22732 nk_filter_default(const struct nk_text_edit *box, nk_rune unicode)
22733 {
22734  NK_UNUSED(unicode);
22735  NK_UNUSED(box);
22736  return nk_true;
22737 }
22738 NK_API int
22739 nk_filter_ascii(const struct nk_text_edit *box, nk_rune unicode)
22740 {
22741  NK_UNUSED(box);
22742  if (unicode > 128) return nk_false;
22743  else return nk_true;
22744 }
22745 NK_API int
22746 nk_filter_float(const struct nk_text_edit *box, nk_rune unicode)
22747 {
22748  NK_UNUSED(box);
22749  if ((unicode < '0' || unicode > '9') && unicode != '.' && unicode != '-')
22750  return nk_false;
22751  else return nk_true;
22752 }
22753 NK_API int
22754 nk_filter_decimal(const struct nk_text_edit *box, nk_rune unicode)
22755 {
22756  NK_UNUSED(box);
22757  if ((unicode < '0' || unicode > '9') && unicode != '-')
22758  return nk_false;
22759  else return nk_true;
22760 }
22761 NK_API int
22762 nk_filter_hex(const struct nk_text_edit *box, nk_rune unicode)
22763 {
22764  NK_UNUSED(box);
22765  if ((unicode < '0' || unicode > '9') &&
22766  (unicode < 'a' || unicode > 'f') &&
22767  (unicode < 'A' || unicode > 'F'))
22768  return nk_false;
22769  else return nk_true;
22770 }
22771 NK_API int
22772 nk_filter_oct(const struct nk_text_edit *box, nk_rune unicode)
22773 {
22774  NK_UNUSED(box);
22775  if (unicode < '0' || unicode > '7')
22776  return nk_false;
22777  else return nk_true;
22778 }
22779 NK_API int
22780 nk_filter_binary(const struct nk_text_edit *box, nk_rune unicode)
22781 {
22782  NK_UNUSED(box);
22783  if (unicode != '0' && unicode != '1')
22784  return nk_false;
22785  else return nk_true;
22786 }
22787 
22788 /* ===============================================================
22789  *
22790  * EDIT
22791  *
22792  * ===============================================================*/
22793 NK_LIB void
22794 nk_edit_draw_text(struct nk_command_buffer *out,
22795  const struct nk_style_edit *style, float pos_x, float pos_y,
22796  float x_offset, const char *text, int byte_len, float row_height,
22797  const struct nk_user_font *font, struct nk_color background,
22798  struct nk_color foreground, int is_selected)
22799 {
22800  NK_ASSERT(out);
22801  NK_ASSERT(font);
22802  NK_ASSERT(style);
22803  if (!text || !byte_len || !out || !style) return;
22804 
22805  {int glyph_len = 0;
22806  nk_rune unicode = 0;
22807  int text_len = 0;
22808  float line_width = 0;
22809  float glyph_width;
22810  const char *line = text;
22811  float line_offset = 0;
22812  int line_count = 0;
22813 
22814  struct nk_text txt;
22815  txt.padding = nk_vec2(0,0);
22816  txt.background = background;
22817  txt.text = foreground;
22818 
22819  glyph_len = nk_utf_decode(text+text_len, &unicode, byte_len-text_len);
22820  if (!glyph_len) return;
22821  while ((text_len < byte_len) && glyph_len)
22822  {
22823  if (unicode == '\n') {
22824  /* new line separator so draw previous line */
22825  struct nk_rect label;
22826  label.y = pos_y + line_offset;
22827  label.h = row_height;
22828  label.w = line_width;
22829  label.x = pos_x;
22830  if (!line_count)
22831  label.x += x_offset;
22832 
22833  if (is_selected) /* selection needs to draw different background color */
22834  nk_fill_rect(out, label, 0, background);
22835  nk_widget_text(out, label, line, (int)((text + text_len) - line),
22836  &txt, NK_TEXT_CENTERED, font);
22837 
22838  text_len++;
22839  line_count++;
22840  line_width = 0;
22841  line = text + text_len;
22842  line_offset += row_height;
22843  glyph_len = nk_utf_decode(text + text_len, &unicode, (int)(byte_len-text_len));
22844  continue;
22845  }
22846  if (unicode == '\r') {
22847  text_len++;
22848  glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len-text_len);
22849  continue;
22850  }
22851  glyph_width = font->width(font->userdata, font->height, text+text_len, glyph_len);
22852  line_width += (float)glyph_width;
22853  text_len += glyph_len;
22854  glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len-text_len);
22855  continue;
22856  }
22857  if (line_width > 0) {
22858  /* draw last line */
22859  struct nk_rect label;
22860  label.y = pos_y + line_offset;
22861  label.h = row_height;
22862  label.w = line_width;
22863  label.x = pos_x;
22864  if (!line_count)
22865  label.x += x_offset;
22866 
22867  if (is_selected)
22868  nk_fill_rect(out, label, 0, background);
22869  nk_widget_text(out, label, line, (int)((text + text_len) - line),
22870  &txt, NK_TEXT_LEFT, font);
22871  }}
22872 }
22874 nk_do_edit(nk_flags *state, struct nk_command_buffer *out,
22875  struct nk_rect bounds, nk_flags flags, nk_plugin_filter filter,
22876  struct nk_text_edit *edit, const struct nk_style_edit *style,
22877  struct nk_input *in, const struct nk_user_font *font)
22878 {
22879  struct nk_rect area;
22880  nk_flags ret = 0;
22881  float row_height;
22882  char prev_state = 0;
22883  char is_hovered = 0;
22884  char select_all = 0;
22885  char cursor_follow = 0;
22886  struct nk_rect old_clip;
22887  struct nk_rect clip;
22888 
22889  NK_ASSERT(state);
22890  NK_ASSERT(out);
22891  NK_ASSERT(style);
22892  if (!state || !out || !style)
22893  return ret;
22894 
22895  /* visible text area calculation */
22896  area.x = bounds.x + style->padding.x + style->border;
22897  area.y = bounds.y + style->padding.y + style->border;
22898  area.w = bounds.w - (2.0f * style->padding.x + 2 * style->border);
22899  area.h = bounds.h - (2.0f * style->padding.y + 2 * style->border);
22900  if (flags & NK_EDIT_MULTILINE)
22901  area.w = NK_MAX(0, area.w - style->scrollbar_size.x);
22902  row_height = (flags & NK_EDIT_MULTILINE)? font->height + style->row_padding: area.h;
22903 
22904  /* calculate clipping rectangle */
22905  old_clip = out->clip;
22906  nk_unify(&clip, &old_clip, area.x, area.y, area.x + area.w, area.y + area.h);
22907 
22908  /* update edit state */
22909  prev_state = (char)edit->active;
22910  is_hovered = (char)nk_input_is_mouse_hovering_rect(in, bounds);
22912  edit->active = NK_INBOX(in->mouse.pos.x, in->mouse.pos.y,
22913  bounds.x, bounds.y, bounds.w, bounds.h);
22914  }
22915 
22916  /* (de)activate text editor */
22917  if (!prev_state && edit->active) {
22918  const enum nk_text_edit_type type = (flags & NK_EDIT_MULTILINE) ?
22920  nk_textedit_clear_state(edit, type, filter);
22921  if (flags & NK_EDIT_AUTO_SELECT)
22922  select_all = nk_true;
22923  if (flags & NK_EDIT_GOTO_END_ON_ACTIVATE) {
22924  edit->cursor = edit->string.len;
22925  in = 0;
22926  }
22927  } else if (!edit->active) edit->mode = NK_TEXT_EDIT_MODE_VIEW;
22928  if (flags & NK_EDIT_READ_ONLY)
22929  edit->mode = NK_TEXT_EDIT_MODE_VIEW;
22930  else if (flags & NK_EDIT_ALWAYS_INSERT_MODE)
22932 
22933  ret = (edit->active) ? NK_EDIT_ACTIVE: NK_EDIT_INACTIVE;
22934  if (prev_state != edit->active)
22935  ret |= (edit->active) ? NK_EDIT_ACTIVATED: NK_EDIT_DEACTIVATED;
22936 
22937  /* handle user input */
22938  if (edit->active && in)
22939  {
22940  int shift_mod = in->keyboard.keys[NK_KEY_SHIFT].down;
22941  const float mouse_x = (in->mouse.pos.x - area.x) + edit->scrollbar.x;
22942  const float mouse_y = (in->mouse.pos.y - area.y) + edit->scrollbar.y;
22943 
22944  /* mouse click handler */
22945  is_hovered = (char)nk_input_is_mouse_hovering_rect(in, area);
22946  if (select_all) {
22947  nk_textedit_select_all(edit);
22948  } else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down &&
22950  nk_textedit_click(edit, mouse_x, mouse_y, font, row_height);
22951  } else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down &&
22952  (in->mouse.delta.x != 0.0f || in->mouse.delta.y != 0.0f)) {
22953  nk_textedit_drag(edit, mouse_x, mouse_y, font, row_height);
22954  cursor_follow = nk_true;
22955  } else if (is_hovered && in->mouse.buttons[NK_BUTTON_RIGHT].clicked &&
22957  nk_textedit_key(edit, NK_KEY_TEXT_WORD_LEFT, nk_false, font, row_height);
22958  nk_textedit_key(edit, NK_KEY_TEXT_WORD_RIGHT, nk_true, font, row_height);
22959  cursor_follow = nk_true;
22960  }
22961 
22962  {int i; /* keyboard input */
22963  int old_mode = edit->mode;
22964  for (i = 0; i < NK_KEY_MAX; ++i) {
22965  if (i == NK_KEY_ENTER || i == NK_KEY_TAB) continue; /* special case */
22966  if (nk_input_is_key_pressed(in, (enum nk_keys)i)) {
22967  nk_textedit_key(edit, (enum nk_keys)i, shift_mod, font, row_height);
22968  cursor_follow = nk_true;
22969  }
22970  }
22971  if (old_mode != edit->mode) {
22972  in->keyboard.text_len = 0;
22973  }}
22974 
22975  /* text input */
22976  edit->filter = filter;
22977  if (in->keyboard.text_len) {
22979  cursor_follow = nk_true;
22980  in->keyboard.text_len = 0;
22981  }
22982 
22983  /* enter key handler */
22985  cursor_follow = nk_true;
22986  if (flags & NK_EDIT_CTRL_ENTER_NEWLINE && shift_mod)
22987  nk_textedit_text(edit, "\n", 1);
22988  else if (flags & NK_EDIT_SIG_ENTER)
22989  ret |= NK_EDIT_COMMITED;
22990  else nk_textedit_text(edit, "\n", 1);
22991  }
22992 
22993  /* cut & copy handler */
22994  {int copy= nk_input_is_key_pressed(in, NK_KEY_COPY);
22995  int cut = nk_input_is_key_pressed(in, NK_KEY_CUT);
22996  if ((copy || cut) && (flags & NK_EDIT_CLIPBOARD))
22997  {
22998  int glyph_len;
22999  nk_rune unicode;
23000  const char *text;
23001  int b = edit->select_start;
23002  int e = edit->select_end;
23003 
23004  int begin = NK_MIN(b, e);
23005  int end = NK_MAX(b, e);
23006  text = nk_str_at_const(&edit->string, begin, &unicode, &glyph_len);
23007  if (edit->clip.copy)
23008  edit->clip.copy(edit->clip.userdata, text, end - begin);
23009  if (cut && !(flags & NK_EDIT_READ_ONLY)){
23010  nk_textedit_cut(edit);
23011  cursor_follow = nk_true;
23012  }
23013  }}
23014 
23015  /* paste handler */
23016  {int paste = nk_input_is_key_pressed(in, NK_KEY_PASTE);
23017  if (paste && (flags & NK_EDIT_CLIPBOARD) && edit->clip.paste) {
23018  edit->clip.paste(edit->clip.userdata, edit);
23019  cursor_follow = nk_true;
23020  }}
23021 
23022  /* tab handler */
23023  {int tab = nk_input_is_key_pressed(in, NK_KEY_TAB);
23024  if (tab && (flags & NK_EDIT_ALLOW_TAB)) {
23025  nk_textedit_text(edit, " ", 4);
23026  cursor_follow = nk_true;
23027  }}
23028  }
23029 
23030  /* set widget state */
23031  if (edit->active)
23032  *state = NK_WIDGET_STATE_ACTIVE;
23033  else nk_widget_state_reset(state);
23034 
23035  if (is_hovered)
23036  *state |= NK_WIDGET_STATE_HOVERED;
23037 
23038  /* DRAW EDIT */
23039  {const char *text = nk_str_get_const(&edit->string);
23040  int len = nk_str_len_char(&edit->string);
23041 
23042  {/* select background colors/images */
23043  const struct nk_style_item *background;
23044  if (*state & NK_WIDGET_STATE_ACTIVED)
23045  background = &style->active;
23046  else if (*state & NK_WIDGET_STATE_HOVER)
23047  background = &style->hover;
23048  else background = &style->normal;
23049 
23050  /* draw background frame */
23051  if (background->type == NK_STYLE_ITEM_COLOR) {
23052  nk_stroke_rect(out, bounds, style->rounding, style->border, style->border_color);
23053  nk_fill_rect(out, bounds, style->rounding, background->data.color);
23054  } else nk_draw_image(out, bounds, &background->data.image, nk_white);}
23055 
23056  area.w = NK_MAX(0, area.w - style->cursor_size);
23057  if (edit->active)
23058  {
23059  int total_lines = 1;
23060  struct nk_vec2 text_size = nk_vec2(0,0);
23061 
23062  /* text pointer positions */
23063  const char *cursor_ptr = 0;
23064  const char *select_begin_ptr = 0;
23065  const char *select_end_ptr = 0;
23066 
23067  /* 2D pixel positions */
23068  struct nk_vec2 cursor_pos = nk_vec2(0,0);
23069  struct nk_vec2 selection_offset_start = nk_vec2(0,0);
23070  struct nk_vec2 selection_offset_end = nk_vec2(0,0);
23071 
23072  int selection_begin = NK_MIN(edit->select_start, edit->select_end);
23073  int selection_end = NK_MAX(edit->select_start, edit->select_end);
23074 
23075  /* calculate total line count + total space + cursor/selection position */
23076  float line_width = 0.0f;
23077  if (text && len)
23078  {
23079  /* utf8 encoding */
23080  float glyph_width;
23081  int glyph_len = 0;
23082  nk_rune unicode = 0;
23083  int text_len = 0;
23084  int glyphs = 0;
23085  int row_begin = 0;
23086 
23087  glyph_len = nk_utf_decode(text, &unicode, len);
23088  glyph_width = font->width(font->userdata, font->height, text, glyph_len);
23089  line_width = 0;
23090 
23091  /* iterate all lines */
23092  while ((text_len < len) && glyph_len)
23093  {
23094  /* set cursor 2D position and line */
23095  if (!cursor_ptr && glyphs == edit->cursor)
23096  {
23097  int glyph_offset;
23098  struct nk_vec2 out_offset;
23099  struct nk_vec2 row_size;
23100  const char *remaining;
23101 
23102  /* calculate 2d position */
23103  cursor_pos.y = (float)(total_lines-1) * row_height;
23104  row_size = nk_text_calculate_text_bounds(font, text+row_begin,
23105  text_len-row_begin, row_height, &remaining,
23106  &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
23107  cursor_pos.x = row_size.x;
23108  cursor_ptr = text + text_len;
23109  }
23110 
23111  /* set start selection 2D position and line */
23112  if (!select_begin_ptr && edit->select_start != edit->select_end &&
23113  glyphs == selection_begin)
23114  {
23115  int glyph_offset;
23116  struct nk_vec2 out_offset;
23117  struct nk_vec2 row_size;
23118  const char *remaining;
23119 
23120  /* calculate 2d position */
23121  selection_offset_start.y = (float)(NK_MAX(total_lines-1,0)) * row_height;
23122  row_size = nk_text_calculate_text_bounds(font, text+row_begin,
23123  text_len-row_begin, row_height, &remaining,
23124  &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
23125  selection_offset_start.x = row_size.x;
23126  select_begin_ptr = text + text_len;
23127  }
23128 
23129  /* set end selection 2D position and line */
23130  if (!select_end_ptr && edit->select_start != edit->select_end &&
23131  glyphs == selection_end)
23132  {
23133  int glyph_offset;
23134  struct nk_vec2 out_offset;
23135  struct nk_vec2 row_size;
23136  const char *remaining;
23137 
23138  /* calculate 2d position */
23139  selection_offset_end.y = (float)(total_lines-1) * row_height;
23140  row_size = nk_text_calculate_text_bounds(font, text+row_begin,
23141  text_len-row_begin, row_height, &remaining,
23142  &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
23143  selection_offset_end.x = row_size.x;
23144  select_end_ptr = text + text_len;
23145  }
23146  if (unicode == '\n') {
23147  text_size.x = NK_MAX(text_size.x, line_width);
23148  total_lines++;
23149  line_width = 0;
23150  text_len++;
23151  glyphs++;
23152  row_begin = text_len;
23153  glyph_len = nk_utf_decode(text + text_len, &unicode, len-text_len);
23154  glyph_width = font->width(font->userdata, font->height, text+text_len, glyph_len);
23155  continue;
23156  }
23157 
23158  glyphs++;
23159  text_len += glyph_len;
23160  line_width += (float)glyph_width;
23161 
23162  glyph_len = nk_utf_decode(text + text_len, &unicode, len-text_len);
23163  glyph_width = font->width(font->userdata, font->height,
23164  text+text_len, glyph_len);
23165  continue;
23166  }
23167  text_size.y = (float)total_lines * row_height;
23168 
23169  /* handle case when cursor is at end of text buffer */
23170  if (!cursor_ptr && edit->cursor == edit->string.len) {
23171  cursor_pos.x = line_width;
23172  cursor_pos.y = text_size.y - row_height;
23173  }
23174  }
23175  {
23176  /* scrollbar */
23177  if (cursor_follow)
23178  {
23179  /* update scrollbar to follow cursor */
23180  if (!(flags & NK_EDIT_NO_HORIZONTAL_SCROLL)) {
23181  /* horizontal scroll */
23182  const float scroll_increment = area.w * 0.25f;
23183  if (cursor_pos.x < edit->scrollbar.x)
23184  edit->scrollbar.x = (float)(int)NK_MAX(0.0f, cursor_pos.x - scroll_increment);
23185  if (cursor_pos.x >= edit->scrollbar.x + area.w)
23186  edit->scrollbar.x = (float)(int)NK_MAX(0.0f, edit->scrollbar.x + scroll_increment);
23187  } else edit->scrollbar.x = 0;
23188 
23189  if (flags & NK_EDIT_MULTILINE) {
23190  /* vertical scroll */
23191  if (cursor_pos.y < edit->scrollbar.y)
23192  edit->scrollbar.y = NK_MAX(0.0f, cursor_pos.y - row_height);
23193  if (cursor_pos.y >= edit->scrollbar.y + area.h)
23194  edit->scrollbar.y = edit->scrollbar.y + row_height;
23195  } else edit->scrollbar.y = 0;
23196  }
23197 
23198  /* scrollbar widget */
23199  if (flags & NK_EDIT_MULTILINE)
23200  {
23201  nk_flags ws;
23202  struct nk_rect scroll;
23203  float scroll_target;
23204  float scroll_offset;
23205  float scroll_step;
23206  float scroll_inc;
23207 
23208  scroll = area;
23209  scroll.x = (bounds.x + bounds.w - style->border) - style->scrollbar_size.x;
23210  scroll.w = style->scrollbar_size.x;
23211 
23212  scroll_offset = edit->scrollbar.y;
23213  scroll_step = scroll.h * 0.10f;
23214  scroll_inc = scroll.h * 0.01f;
23215  scroll_target = text_size.y;
23216  edit->scrollbar.y = nk_do_scrollbarv(&ws, out, scroll, 0,
23217  scroll_offset, scroll_target, scroll_step, scroll_inc,
23218  &style->scrollbar, in, font);
23219  }
23220  }
23221 
23222  /* draw text */
23223  {struct nk_color background_color;
23224  struct nk_color text_color;
23225  struct nk_color sel_background_color;
23226  struct nk_color sel_text_color;
23227  struct nk_color cursor_color;
23228  struct nk_color cursor_text_color;
23229  const struct nk_style_item *background;
23230  nk_push_scissor(out, clip);
23231 
23232  /* select correct colors to draw */
23233  if (*state & NK_WIDGET_STATE_ACTIVED) {
23234  background = &style->active;
23235  text_color = style->text_active;
23236  sel_text_color = style->selected_text_hover;
23237  sel_background_color = style->selected_hover;
23238  cursor_color = style->cursor_hover;
23239  cursor_text_color = style->cursor_text_hover;
23240  } else if (*state & NK_WIDGET_STATE_HOVER) {
23241  background = &style->hover;
23242  text_color = style->text_hover;
23243  sel_text_color = style->selected_text_hover;
23244  sel_background_color = style->selected_hover;
23245  cursor_text_color = style->cursor_text_hover;
23246  cursor_color = style->cursor_hover;
23247  } else {
23248  background = &style->normal;
23249  text_color = style->text_normal;
23250  sel_text_color = style->selected_text_normal;
23251  sel_background_color = style->selected_normal;
23252  cursor_color = style->cursor_normal;
23253  cursor_text_color = style->cursor_text_normal;
23254  }
23255  if (background->type == NK_STYLE_ITEM_IMAGE)
23256  background_color = nk_rgba(0,0,0,0);
23257  else background_color = background->data.color;
23258 
23259 
23260  if (edit->select_start == edit->select_end) {
23261  /* no selection so just draw the complete text */
23262  const char *begin = nk_str_get_const(&edit->string);
23263  int l = nk_str_len_char(&edit->string);
23264  nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
23265  area.y - edit->scrollbar.y, 0, begin, l, row_height, font,
23266  background_color, text_color, nk_false);
23267  } else {
23268  /* edit has selection so draw 1-3 text chunks */
23269  if (edit->select_start != edit->select_end && selection_begin > 0){
23270  /* draw unselected text before selection */
23271  const char *begin = nk_str_get_const(&edit->string);
23272  NK_ASSERT(select_begin_ptr);
23273  nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
23274  area.y - edit->scrollbar.y, 0, begin, (int)(select_begin_ptr - begin),
23275  row_height, font, background_color, text_color, nk_false);
23276  }
23277  if (edit->select_start != edit->select_end) {
23278  /* draw selected text */
23279  NK_ASSERT(select_begin_ptr);
23280  if (!select_end_ptr) {
23281  const char *begin = nk_str_get_const(&edit->string);
23282  select_end_ptr = begin + nk_str_len_char(&edit->string);
23283  }
23284  nk_edit_draw_text(out, style,
23285  area.x - edit->scrollbar.x,
23286  area.y + selection_offset_start.y - edit->scrollbar.y,
23287  selection_offset_start.x,
23288  select_begin_ptr, (int)(select_end_ptr - select_begin_ptr),
23289  row_height, font, sel_background_color, sel_text_color, nk_true);
23290  }
23291  if ((edit->select_start != edit->select_end &&
23292  selection_end < edit->string.len))
23293  {
23294  /* draw unselected text after selected text */
23295  const char *begin = select_end_ptr;
23296  const char *end = nk_str_get_const(&edit->string) +
23297  nk_str_len_char(&edit->string);
23298  NK_ASSERT(select_end_ptr);
23299  nk_edit_draw_text(out, style,
23300  area.x - edit->scrollbar.x,
23301  area.y + selection_offset_end.y - edit->scrollbar.y,
23302  selection_offset_end.x,
23303  begin, (int)(end - begin), row_height, font,
23304  background_color, text_color, nk_true);
23305  }
23306  }
23307 
23308  /* cursor */
23309  if (edit->select_start == edit->select_end)
23310  {
23311  if (edit->cursor >= nk_str_len(&edit->string) ||
23312  (cursor_ptr && *cursor_ptr == '\n')) {
23313  /* draw cursor at end of line */
23314  struct nk_rect cursor;
23315  cursor.w = style->cursor_size;
23316  cursor.h = font->height;
23317  cursor.x = area.x + cursor_pos.x - edit->scrollbar.x;
23318  cursor.y = area.y + cursor_pos.y + row_height/2.0f - cursor.h/2.0f;
23319  cursor.y -= edit->scrollbar.y;
23320  nk_fill_rect(out, cursor, 0, cursor_color);
23321  } else {
23322  /* draw cursor inside text */
23323  int glyph_len;
23324  struct nk_rect label;
23325  struct nk_text txt;
23326 
23327  nk_rune unicode;
23328  NK_ASSERT(cursor_ptr);
23329  glyph_len = nk_utf_decode(cursor_ptr, &unicode, 4);
23330 
23331  label.x = area.x + cursor_pos.x - edit->scrollbar.x;
23332  label.y = area.y + cursor_pos.y - edit->scrollbar.y;
23333  label.w = font->width(font->userdata, font->height, cursor_ptr, glyph_len);
23334  label.h = row_height;
23335 
23336  txt.padding = nk_vec2(0,0);
23337  txt.background = cursor_color;;
23338  txt.text = cursor_text_color;
23339  nk_fill_rect(out, label, 0, cursor_color);
23340  nk_widget_text(out, label, cursor_ptr, glyph_len, &txt, NK_TEXT_LEFT, font);
23341  }
23342  }}
23343  } else {
23344  /* not active so just draw text */
23345  int l = nk_str_len_char(&edit->string);
23346  const char *begin = nk_str_get_const(&edit->string);
23347 
23348  const struct nk_style_item *background;
23349  struct nk_color background_color;
23350  struct nk_color text_color;
23351  nk_push_scissor(out, clip);
23352  if (*state & NK_WIDGET_STATE_ACTIVED) {
23353  background = &style->active;
23354  text_color = style->text_active;
23355  } else if (*state & NK_WIDGET_STATE_HOVER) {
23356  background = &style->hover;
23357  text_color = style->text_hover;
23358  } else {
23359  background = &style->normal;
23360  text_color = style->text_normal;
23361  }
23362  if (background->type == NK_STYLE_ITEM_IMAGE)
23363  background_color = nk_rgba(0,0,0,0);
23364  else background_color = background->data.color;
23365  nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
23366  area.y - edit->scrollbar.y, 0, begin, l, row_height, font,
23367  background_color, text_color, nk_false);
23368  }
23369  nk_push_scissor(out, old_clip);}
23370  return ret;
23371 }
23372 NK_API void
23373 nk_edit_focus(struct nk_context *ctx, nk_flags flags)
23374 {
23375  nk_hash hash;
23376  struct nk_window *win;
23377 
23378  NK_ASSERT(ctx);
23379  NK_ASSERT(ctx->current);
23380  if (!ctx || !ctx->current) return;
23381 
23382  win = ctx->current;
23383  hash = win->edit.seq;
23384  win->edit.active = nk_true;
23385  win->edit.name = hash;
23388 }
23389 NK_API void
23391 {
23392  struct nk_window *win;
23393  NK_ASSERT(ctx);
23394  NK_ASSERT(ctx->current);
23395  if (!ctx || !ctx->current) return;
23396 
23397  win = ctx->current;
23398  win->edit.active = nk_false;
23399  win->edit.name = 0;
23400 }
23403  char *memory, int *len, int max, nk_plugin_filter filter)
23404 {
23405  nk_hash hash;
23406  nk_flags state;
23407  struct nk_text_edit *edit;
23408  struct nk_window *win;
23409 
23410  NK_ASSERT(ctx);
23411  NK_ASSERT(memory);
23412  NK_ASSERT(len);
23413  if (!ctx || !memory || !len)
23414  return 0;
23415 
23416  filter = (!filter) ? nk_filter_default: filter;
23417  win = ctx->current;
23418  hash = win->edit.seq;
23419  edit = &ctx->text_edit;
23420  nk_textedit_clear_state(&ctx->text_edit, (flags & NK_EDIT_MULTILINE)?
23422 
23423  if (win->edit.active && hash == win->edit.name) {
23424  if (flags & NK_EDIT_NO_CURSOR)
23425  edit->cursor = nk_utf_len(memory, *len);
23426  else edit->cursor = win->edit.cursor;
23427  if (!(flags & NK_EDIT_SELECTABLE)) {
23428  edit->select_start = win->edit.cursor;
23429  edit->select_end = win->edit.cursor;
23430  } else {
23431  edit->select_start = win->edit.sel_start;
23432  edit->select_end = win->edit.sel_end;
23433  }
23434  edit->mode = win->edit.mode;
23435  edit->scrollbar.x = (float)win->edit.scrollbar.x;
23436  edit->scrollbar.y = (float)win->edit.scrollbar.y;
23437  edit->active = nk_true;
23438  } else edit->active = nk_false;
23439 
23440  max = NK_MAX(1, max);
23441  *len = NK_MIN(*len, max-1);
23442  nk_str_init_fixed(&edit->string, memory, (nk_size)max);
23443  edit->string.buffer.allocated = (nk_size)*len;
23444  edit->string.len = nk_utf_len(memory, *len);
23445  state = nk_edit_buffer(ctx, flags, edit, filter);
23446  *len = (int)edit->string.buffer.allocated;
23447 
23448  if (edit->active) {
23449  win->edit.cursor = edit->cursor;
23450  win->edit.sel_start = edit->select_start;
23451  win->edit.sel_end = edit->select_end;
23452  win->edit.mode = edit->mode;
23453  win->edit.scrollbar.x = (nk_uint)edit->scrollbar.x;
23454  win->edit.scrollbar.y = (nk_uint)edit->scrollbar.y;
23455  } return state;
23456 }
23459  struct nk_text_edit *edit, nk_plugin_filter filter)
23460 {
23461  struct nk_window *win;
23462  struct nk_style *style;
23463  struct nk_input *in;
23464 
23465  enum nk_widget_layout_states state;
23466  struct nk_rect bounds;
23467 
23468  nk_flags ret_flags = 0;
23469  unsigned char prev_state;
23470  nk_hash hash;
23471 
23472  /* make sure correct values */
23473  NK_ASSERT(ctx);
23474  NK_ASSERT(edit);
23475  NK_ASSERT(ctx->current);
23476  NK_ASSERT(ctx->current->layout);
23477  if (!ctx || !ctx->current || !ctx->current->layout)
23478  return 0;
23479 
23480  win = ctx->current;
23481  style = &ctx->style;
23482  state = nk_widget(&bounds, ctx);
23483  if (!state) return state;
23484  in = (win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
23485 
23486  /* check if edit is currently hot item */
23487  hash = win->edit.seq++;
23488  if (win->edit.active && hash == win->edit.name) {
23489  if (flags & NK_EDIT_NO_CURSOR)
23490  edit->cursor = edit->string.len;
23491  if (!(flags & NK_EDIT_SELECTABLE)) {
23492  edit->select_start = edit->cursor;
23493  edit->select_end = edit->cursor;
23494  }
23495  if (flags & NK_EDIT_CLIPBOARD)
23496  edit->clip = ctx->clip;
23497  edit->active = (unsigned char)win->edit.active;
23498  } else edit->active = nk_false;
23499  edit->mode = win->edit.mode;
23500 
23501  filter = (!filter) ? nk_filter_default: filter;
23502  prev_state = (unsigned char)edit->active;
23503  in = (flags & NK_EDIT_READ_ONLY) ? 0: in;
23504  ret_flags = nk_do_edit(&ctx->last_widget_state, &win->buffer, bounds, flags,
23505  filter, edit, &style->edit, in, style->font);
23506 
23509  if (edit->active && prev_state != edit->active) {
23510  /* current edit is now hot */
23511  win->edit.active = nk_true;
23512  win->edit.name = hash;
23513  } else if (prev_state && !edit->active) {
23514  /* current edit is now cold */
23515  win->edit.active = nk_false;
23516  } return ret_flags;
23517 }
23520  char *buffer, int max, nk_plugin_filter filter)
23521 {
23522  nk_flags result;
23523  int len = nk_strlen(buffer);
23524  result = nk_edit_string(ctx, flags, buffer, &len, max, filter);
23525  buffer[NK_MIN(NK_MAX(max-1,0), len)] = '\0';
23526  return result;
23527 }
23528 
23529 
23530 
23531 
23532 
23533 /* ===============================================================
23534  *
23535  * PROPERTY
23536  *
23537  * ===============================================================*/
23538 NK_LIB void
23539 nk_drag_behavior(nk_flags *state, const struct nk_input *in,
23540  struct nk_rect drag, struct nk_property_variant *variant,
23541  float inc_per_pixel)
23542 {
23543  int left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
23544  int left_mouse_click_in_cursor = in &&
23546 
23547  nk_widget_state_reset(state);
23548  if (nk_input_is_mouse_hovering_rect(in, drag))
23549  *state = NK_WIDGET_STATE_HOVERED;
23550 
23551  if (left_mouse_down && left_mouse_click_in_cursor) {
23552  float delta, pixels;
23553  pixels = in->mouse.delta.x;
23554  delta = pixels * inc_per_pixel;
23555  switch (variant->kind) {
23556  default: break;
23557  case NK_PROPERTY_INT:
23558  variant->value.i = variant->value.i + (int)delta;
23559  variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
23560  break;
23561  case NK_PROPERTY_FLOAT:
23562  variant->value.f = variant->value.f + (float)delta;
23563  variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
23564  break;
23565  case NK_PROPERTY_DOUBLE:
23566  variant->value.d = variant->value.d + (double)delta;
23567  variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
23568  break;
23569  }
23570  *state = NK_WIDGET_STATE_ACTIVE;
23571  }
23573  *state |= NK_WIDGET_STATE_ENTERED;
23574  else if (nk_input_is_mouse_prev_hovering_rect(in, drag))
23575  *state |= NK_WIDGET_STATE_LEFT;
23576 }
23577 NK_LIB void
23578 nk_property_behavior(nk_flags *ws, const struct nk_input *in,
23579  struct nk_rect property, struct nk_rect label, struct nk_rect edit,
23580  struct nk_rect empty, int *state, struct nk_property_variant *variant,
23581  float inc_per_pixel)
23582 {
23583  if (in && *state == NK_PROPERTY_DEFAULT) {
23584  if (nk_button_behavior(ws, edit, in, NK_BUTTON_DEFAULT))
23585  *state = NK_PROPERTY_EDIT;
23587  *state = NK_PROPERTY_DRAG;
23589  *state = NK_PROPERTY_DRAG;
23590  }
23591  if (*state == NK_PROPERTY_DRAG) {
23592  nk_drag_behavior(ws, in, property, variant, inc_per_pixel);
23593  if (!(*ws & NK_WIDGET_STATE_ACTIVED)) *state = NK_PROPERTY_DEFAULT;
23594  }
23595 }
23596 NK_LIB void
23597 nk_draw_property(struct nk_command_buffer *out, const struct nk_style_property *style,
23598  const struct nk_rect *bounds, const struct nk_rect *label, nk_flags state,
23599  const char *name, int len, const struct nk_user_font *font)
23600 {
23601  struct nk_text text;
23602  const struct nk_style_item *background;
23603 
23604  /* select correct background and text color */
23605  if (state & NK_WIDGET_STATE_ACTIVED) {
23606  background = &style->active;
23607  text.text = style->label_active;
23608  } else if (state & NK_WIDGET_STATE_HOVER) {
23609  background = &style->hover;
23610  text.text = style->label_hover;
23611  } else {
23612  background = &style->normal;
23613  text.text = style->label_normal;
23614  }
23615 
23616  /* draw background */
23617  if (background->type == NK_STYLE_ITEM_IMAGE) {
23618  nk_draw_image(out, *bounds, &background->data.image, nk_white);
23619  text.background = nk_rgba(0,0,0,0);
23620  } else {
23621  text.background = background->data.color;
23622  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
23623  nk_stroke_rect(out, *bounds, style->rounding, style->border, background->data.color);
23624  }
23625 
23626  /* draw label */
23627  text.padding = nk_vec2(0,0);
23628  nk_widget_text(out, *label, name, len, &text, NK_TEXT_CENTERED, font);
23629 }
23630 NK_LIB void
23631 nk_do_property(nk_flags *ws,
23632  struct nk_command_buffer *out, struct nk_rect property,
23633  const char *name, struct nk_property_variant *variant,
23634  float inc_per_pixel, char *buffer, int *len,
23635  int *state, int *cursor, int *select_begin, int *select_end,
23636  const struct nk_style_property *style,
23637  enum nk_property_filter filter, struct nk_input *in,
23638  const struct nk_user_font *font, struct nk_text_edit *text_edit,
23639  enum nk_button_behavior behavior)
23640 {
23641  const nk_plugin_filter filters[] = {
23644  };
23645  int active, old;
23646  int num_len, name_len;
23647  char string[NK_MAX_NUMBER_BUFFER];
23648  float size;
23649 
23650  char *dst = 0;
23651  int *length;
23652 
23653  struct nk_rect left;
23654  struct nk_rect right;
23655  struct nk_rect label;
23656  struct nk_rect edit;
23657  struct nk_rect empty;
23658 
23659  /* left decrement button */
23660  left.h = font->height/2;
23661  left.w = left.h;
23662  left.x = property.x + style->border + style->padding.x;
23663  left.y = property.y + style->border + property.h/2.0f - left.h/2;
23664 
23665  /* text label */
23666  name_len = nk_strlen(name);
23667  size = font->width(font->userdata, font->height, name, name_len);
23668  label.x = left.x + left.w + style->padding.x;
23669  label.w = (float)size + 2 * style->padding.x;
23670  label.y = property.y + style->border + style->padding.y;
23671  label.h = property.h - (2 * style->border + 2 * style->padding.y);
23672 
23673  /* right increment button */
23674  right.y = left.y;
23675  right.w = left.w;
23676  right.h = left.h;
23677  right.x = property.x + property.w - (right.w + style->padding.x);
23678 
23679  /* edit */
23680  if (*state == NK_PROPERTY_EDIT) {
23681  size = font->width(font->userdata, font->height, buffer, *len);
23682  size += style->edit.cursor_size;
23683  length = len;
23684  dst = buffer;
23685  } else {
23686  switch (variant->kind) {
23687  default: break;
23688  case NK_PROPERTY_INT:
23689  nk_itoa(string, variant->value.i);
23690  num_len = nk_strlen(string);
23691  break;
23692  case NK_PROPERTY_FLOAT:
23693  NK_DTOA(string, (double)variant->value.f);
23694  num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION);
23695  break;
23696  case NK_PROPERTY_DOUBLE:
23697  NK_DTOA(string, variant->value.d);
23698  num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION);
23699  break;
23700  }
23701  size = font->width(font->userdata, font->height, string, num_len);
23702  dst = string;
23703  length = &num_len;
23704  }
23705 
23706  edit.w = (float)size + 2 * style->padding.x;
23707  edit.w = NK_MIN(edit.w, right.x - (label.x + label.w));
23708  edit.x = right.x - (edit.w + style->padding.x);
23709  edit.y = property.y + style->border;
23710  edit.h = property.h - (2 * style->border);
23711 
23712  /* empty left space activator */
23713  empty.w = edit.x - (label.x + label.w);
23714  empty.x = label.x + label.w;
23715  empty.y = property.y;
23716  empty.h = property.h;
23717 
23718  /* update property */
23719  old = (*state == NK_PROPERTY_EDIT);
23720  nk_property_behavior(ws, in, property, label, edit, empty, state, variant, inc_per_pixel);
23721 
23722  /* draw property */
23723  if (style->draw_begin) style->draw_begin(out, style->userdata);
23724  nk_draw_property(out, style, &property, &label, *ws, name, name_len, font);
23725  if (style->draw_end) style->draw_end(out, style->userdata);
23726 
23727  /* execute right button */
23728  if (nk_do_button_symbol(ws, out, left, style->sym_left, behavior, &style->dec_button, in, font)) {
23729  switch (variant->kind) {
23730  default: break;
23731  case NK_PROPERTY_INT:
23732  variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i - variant->step.i, variant->max_value.i); break;
23733  case NK_PROPERTY_FLOAT:
23734  variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f - variant->step.f, variant->max_value.f); break;
23735  case NK_PROPERTY_DOUBLE:
23736  variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d - variant->step.d, variant->max_value.d); break;
23737  }
23738  }
23739  /* execute left button */
23740  if (nk_do_button_symbol(ws, out, right, style->sym_right, behavior, &style->inc_button, in, font)) {
23741  switch (variant->kind) {
23742  default: break;
23743  case NK_PROPERTY_INT:
23744  variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i + variant->step.i, variant->max_value.i); break;
23745  case NK_PROPERTY_FLOAT:
23746  variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f + variant->step.f, variant->max_value.f); break;
23747  case NK_PROPERTY_DOUBLE:
23748  variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d + variant->step.d, variant->max_value.d); break;
23749  }
23750  }
23751  if (old != NK_PROPERTY_EDIT && (*state == NK_PROPERTY_EDIT)) {
23752  /* property has been activated so setup buffer */
23753  NK_MEMCPY(buffer, dst, (nk_size)*length);
23754  *cursor = nk_utf_len(buffer, *length);
23755  *len = *length;
23756  length = len;
23757  dst = buffer;
23758  active = 0;
23759  } else active = (*state == NK_PROPERTY_EDIT);
23760 
23761  /* execute and run text edit field */
23762  nk_textedit_clear_state(text_edit, NK_TEXT_EDIT_SINGLE_LINE, filters[filter]);
23763  text_edit->active = (unsigned char)active;
23764  text_edit->string.len = *length;
23765  text_edit->cursor = NK_CLAMP(0, *cursor, *length);
23766  text_edit->select_start = NK_CLAMP(0,*select_begin, *length);
23767  text_edit->select_end = NK_CLAMP(0,*select_end, *length);
23768  text_edit->string.buffer.allocated = (nk_size)*length;
23770  text_edit->string.buffer.memory.ptr = dst;
23771  text_edit->string.buffer.size = NK_MAX_NUMBER_BUFFER;
23772  text_edit->mode = NK_TEXT_EDIT_MODE_INSERT;
23773  nk_do_edit(ws, out, edit, NK_EDIT_FIELD|NK_EDIT_AUTO_SELECT,
23774  filters[filter], text_edit, &style->edit, (*state == NK_PROPERTY_EDIT) ? in: 0, font);
23775 
23776  *length = text_edit->string.len;
23777  *cursor = text_edit->cursor;
23778  *select_begin = text_edit->select_start;
23779  *select_end = text_edit->select_end;
23780  if (text_edit->active && nk_input_is_key_pressed(in, NK_KEY_ENTER))
23781  text_edit->active = nk_false;
23782 
23783  if (active && !text_edit->active) {
23784  /* property is now not active so convert edit text to value*/
23785  *state = NK_PROPERTY_DEFAULT;
23786  buffer[*len] = '\0';
23787  switch (variant->kind) {
23788  default: break;
23789  case NK_PROPERTY_INT:
23790  variant->value.i = nk_strtoi(buffer, 0);
23791  variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
23792  break;
23793  case NK_PROPERTY_FLOAT:
23794  nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
23795  variant->value.f = nk_strtof(buffer, 0);
23796  variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
23797  break;
23798  case NK_PROPERTY_DOUBLE:
23799  nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
23800  variant->value.d = nk_strtod(buffer, 0);
23801  variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
23802  break;
23803  }
23804  }
23805 }
23806 NK_LIB struct nk_property_variant
23807 nk_property_variant_int(int value, int min_value, int max_value, int step)
23808 {
23809  struct nk_property_variant result;
23810  result.kind = NK_PROPERTY_INT;
23811  result.value.i = value;
23812  result.min_value.i = min_value;
23813  result.max_value.i = max_value;
23814  result.step.i = step;
23815  return result;
23816 }
23817 NK_LIB struct nk_property_variant
23818 nk_property_variant_float(float value, float min_value, float max_value, float step)
23819 {
23820  struct nk_property_variant result;
23821  result.kind = NK_PROPERTY_FLOAT;
23822  result.value.f = value;
23823  result.min_value.f = min_value;
23824  result.max_value.f = max_value;
23825  result.step.f = step;
23826  return result;
23827 }
23828 NK_LIB struct nk_property_variant
23829 nk_property_variant_double(double value, double min_value, double max_value,
23830  double step)
23831 {
23832  struct nk_property_variant result;
23833  result.kind = NK_PROPERTY_DOUBLE;
23834  result.value.d = value;
23835  result.min_value.d = min_value;
23836  result.max_value.d = max_value;
23837  result.step.d = step;
23838  return result;
23839 }
23840 NK_LIB void
23841 nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant *variant,
23842  float inc_per_pixel, const enum nk_property_filter filter)
23843 {
23844  struct nk_window *win;
23845  struct nk_panel *layout;
23846  struct nk_input *in;
23847  const struct nk_style *style;
23848 
23849  struct nk_rect bounds;
23850  enum nk_widget_layout_states s;
23851 
23852  int *state = 0;
23853  nk_hash hash = 0;
23854  char *buffer = 0;
23855  int *len = 0;
23856  int *cursor = 0;
23857  int *select_begin = 0;
23858  int *select_end = 0;
23859  int old_state;
23860 
23861  char dummy_buffer[NK_MAX_NUMBER_BUFFER];
23862  int dummy_state = NK_PROPERTY_DEFAULT;
23863  int dummy_length = 0;
23864  int dummy_cursor = 0;
23865  int dummy_select_begin = 0;
23866  int dummy_select_end = 0;
23867 
23868  NK_ASSERT(ctx);
23869  NK_ASSERT(ctx->current);
23870  NK_ASSERT(ctx->current->layout);
23871  if (!ctx || !ctx->current || !ctx->current->layout)
23872  return;
23873 
23874  win = ctx->current;
23875  layout = win->layout;
23876  style = &ctx->style;
23877  s = nk_widget(&bounds, ctx);
23878  if (!s) return;
23879 
23880  /* calculate hash from name */
23881  if (name[0] == '#') {
23882  hash = nk_murmur_hash(name, (int)nk_strlen(name), win->property.seq++);
23883  name++; /* special number hash */
23884  } else hash = nk_murmur_hash(name, (int)nk_strlen(name), 42);
23885 
23886  /* check if property is currently hot item */
23887  if (win->property.active && hash == win->property.name) {
23888  buffer = win->property.buffer;
23889  len = &win->property.length;
23890  cursor = &win->property.cursor;
23891  state = &win->property.state;
23892  select_begin = &win->property.select_start;
23893  select_end = &win->property.select_end;
23894  } else {
23895  buffer = dummy_buffer;
23896  len = &dummy_length;
23897  cursor = &dummy_cursor;
23898  state = &dummy_state;
23899  select_begin = &dummy_select_begin;
23900  select_end = &dummy_select_end;
23901  }
23902 
23903  /* execute property widget */
23904  old_state = *state;
23905  ctx->text_edit.clip = ctx->clip;
23906  in = ((s == NK_WIDGET_ROM && !win->property.active) ||
23907  layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
23908  nk_do_property(&ctx->last_widget_state, &win->buffer, bounds, name,
23909  variant, inc_per_pixel, buffer, len, state, cursor, select_begin,
23910  select_end, &style->property, filter, in, style->font, &ctx->text_edit,
23911  ctx->button_behavior);
23912 
23913  if (in && *state != NK_PROPERTY_DEFAULT && !win->property.active) {
23914  /* current property is now hot */
23915  win->property.active = 1;
23916  NK_MEMCPY(win->property.buffer, buffer, (nk_size)*len);
23917  win->property.length = *len;
23918  win->property.cursor = *cursor;
23919  win->property.state = *state;
23920  win->property.name = hash;
23921  win->property.select_start = *select_begin;
23922  win->property.select_end = *select_end;
23923  if (*state == NK_PROPERTY_DRAG) {
23924  ctx->input.mouse.grab = nk_true;
23926  }
23927  }
23928  /* check if previously active property is now inactive */
23929  if (*state == NK_PROPERTY_DEFAULT && old_state != NK_PROPERTY_DEFAULT) {
23930  if (old_state == NK_PROPERTY_DRAG) {
23934  }
23935  win->property.select_start = 0;
23936  win->property.select_end = 0;
23937  win->property.active = 0;
23938  }
23939 }
23940 NK_API void
23941 nk_property_int(struct nk_context *ctx, const char *name,
23942  int min, int *val, int max, int step, float inc_per_pixel)
23943 {
23944  struct nk_property_variant variant;
23945  NK_ASSERT(ctx);
23946  NK_ASSERT(name);
23947  NK_ASSERT(val);
23948 
23949  if (!ctx || !ctx->current || !name || !val) return;
23950  variant = nk_property_variant_int(*val, min, max, step);
23951  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT);
23952  *val = variant.value.i;
23953 }
23954 NK_API void
23955 nk_property_float(struct nk_context *ctx, const char *name,
23956  float min, float *val, float max, float step, float inc_per_pixel)
23957 {
23958  struct nk_property_variant variant;
23959  NK_ASSERT(ctx);
23960  NK_ASSERT(name);
23961  NK_ASSERT(val);
23962 
23963  if (!ctx || !ctx->current || !name || !val) return;
23964  variant = nk_property_variant_float(*val, min, max, step);
23965  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
23966  *val = variant.value.f;
23967 }
23968 NK_API void
23969 nk_property_double(struct nk_context *ctx, const char *name,
23970  double min, double *val, double max, double step, float inc_per_pixel)
23971 {
23972  struct nk_property_variant variant;
23973  NK_ASSERT(ctx);
23974  NK_ASSERT(name);
23975  NK_ASSERT(val);
23976 
23977  if (!ctx || !ctx->current || !name || !val) return;
23978  variant = nk_property_variant_double(*val, min, max, step);
23979  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
23980  *val = variant.value.d;
23981 }
23982 NK_API int
23983 nk_propertyi(struct nk_context *ctx, const char *name, int min, int val,
23984  int max, int step, float inc_per_pixel)
23985 {
23986  struct nk_property_variant variant;
23987  NK_ASSERT(ctx);
23988  NK_ASSERT(name);
23989 
23990  if (!ctx || !ctx->current || !name) return val;
23991  variant = nk_property_variant_int(val, min, max, step);
23992  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT);
23993  val = variant.value.i;
23994  return val;
23995 }
23996 NK_API float
23997 nk_propertyf(struct nk_context *ctx, const char *name, float min,
23998  float val, float max, float step, float inc_per_pixel)
23999 {
24000  struct nk_property_variant variant;
24001  NK_ASSERT(ctx);
24002  NK_ASSERT(name);
24003 
24004  if (!ctx || !ctx->current || !name) return val;
24005  variant = nk_property_variant_float(val, min, max, step);
24006  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
24007  val = variant.value.f;
24008  return val;
24009 }
24010 NK_API double
24011 nk_propertyd(struct nk_context *ctx, const char *name, double min,
24012  double val, double max, double step, float inc_per_pixel)
24013 {
24014  struct nk_property_variant variant;
24015  NK_ASSERT(ctx);
24016  NK_ASSERT(name);
24017 
24018  if (!ctx || !ctx->current || !name) return val;
24019  variant = nk_property_variant_double(val, min, max, step);
24020  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
24021  val = variant.value.d;
24022  return val;
24023 }
24024 
24025 
24026 
24027 
24028 
24029 /* ==============================================================
24030  *
24031  * CHART
24032  *
24033  * ===============================================================*/
24034 NK_API int
24036  struct nk_color color, struct nk_color highlight,
24037  int count, float min_value, float max_value)
24038 {
24039  struct nk_window *win;
24040  struct nk_chart *chart;
24041  const struct nk_style *config;
24042  const struct nk_style_chart *style;
24043 
24044  const struct nk_style_item *background;
24045  struct nk_rect bounds = {0, 0, 0, 0};
24046 
24047  NK_ASSERT(ctx);
24048  NK_ASSERT(ctx->current);
24049  NK_ASSERT(ctx->current->layout);
24050 
24051  if (!ctx || !ctx->current || !ctx->current->layout) return 0;
24052  if (!nk_widget(&bounds, ctx)) {
24053  chart = &ctx->current->layout->chart;
24054  nk_zero(chart, sizeof(*chart));
24055  return 0;
24056  }
24057 
24058  win = ctx->current;
24059  config = &ctx->style;
24060  chart = &win->layout->chart;
24061  style = &config->chart;
24062 
24063  /* setup basic generic chart */
24064  nk_zero(chart, sizeof(*chart));
24065  chart->x = bounds.x + style->padding.x;
24066  chart->y = bounds.y + style->padding.y;
24067  chart->w = bounds.w - 2 * style->padding.x;
24068  chart->h = bounds.h - 2 * style->padding.y;
24069  chart->w = NK_MAX(chart->w, 2 * style->padding.x);
24070  chart->h = NK_MAX(chart->h, 2 * style->padding.y);
24071 
24072  /* add first slot into chart */
24073  {struct nk_chart_slot *slot = &chart->slots[chart->slot++];
24074  slot->type = type;
24075  slot->count = count;
24076  slot->color = color;
24077  slot->highlight = highlight;
24078  slot->min = NK_MIN(min_value, max_value);
24079  slot->max = NK_MAX(min_value, max_value);
24080  slot->range = slot->max - slot->min;}
24081 
24082  /* draw chart background */
24083  background = &style->background;
24084  if (background->type == NK_STYLE_ITEM_IMAGE) {
24085  nk_draw_image(&win->buffer, bounds, &background->data.image, nk_white);
24086  } else {
24087  nk_fill_rect(&win->buffer, bounds, style->rounding, style->border_color);
24088  nk_fill_rect(&win->buffer, nk_shrink_rect(bounds, style->border),
24089  style->rounding, style->background.data.color);
24090  }
24091  return 1;
24092 }
24093 NK_API int
24094 nk_chart_begin(struct nk_context *ctx, const enum nk_chart_type type,
24095  int count, float min_value, float max_value)
24096 {
24098  ctx->style.chart.selected_color, count, min_value, max_value);
24099 }
24100 NK_API void
24102  struct nk_color color, struct nk_color highlight,
24103  int count, float min_value, float max_value)
24104 {
24105  NK_ASSERT(ctx);
24106  NK_ASSERT(ctx->current);
24107  NK_ASSERT(ctx->current->layout);
24108  NK_ASSERT(ctx->current->layout->chart.slot < NK_CHART_MAX_SLOT);
24109  if (!ctx || !ctx->current || !ctx->current->layout) return;
24110  if (ctx->current->layout->chart.slot >= NK_CHART_MAX_SLOT) return;
24111 
24112  /* add another slot into the graph */
24113  {struct nk_chart *chart = &ctx->current->layout->chart;
24114  struct nk_chart_slot *slot = &chart->slots[chart->slot++];
24115  slot->type = type;
24116  slot->count = count;
24117  slot->color = color;
24118  slot->highlight = highlight;
24119  slot->min = NK_MIN(min_value, max_value);
24120  slot->max = NK_MAX(min_value, max_value);
24121  slot->range = slot->max - slot->min;}
24122 }
24123 NK_API void
24124 nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type type,
24125  int count, float min_value, float max_value)
24126 {
24128  ctx->style.chart.selected_color, count, min_value, max_value);
24129 }
24131 nk_chart_push_line(struct nk_context *ctx, struct nk_window *win,
24132  struct nk_chart *g, float value, int slot)
24133 {
24134  struct nk_panel *layout = win->layout;
24135  const struct nk_input *i = &ctx->input;
24136  struct nk_command_buffer *out = &win->buffer;
24137 
24138  nk_flags ret = 0;
24139  struct nk_vec2 cur;
24140  struct nk_rect bounds;
24141  struct nk_color color;
24142  float step;
24143  float range;
24144  float ratio;
24145 
24146  NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
24147  step = g->w / (float)g->slots[slot].count;
24148  range = g->slots[slot].max - g->slots[slot].min;
24149  ratio = (value - g->slots[slot].min) / range;
24150 
24151  if (g->slots[slot].index == 0) {
24152  /* first data point does not have a connection */
24153  g->slots[slot].last.x = g->x;
24154  g->slots[slot].last.y = (g->y + g->h) - ratio * (float)g->h;
24155 
24156  bounds.x = g->slots[slot].last.x - 2;
24157  bounds.y = g->slots[slot].last.y - 2;
24158  bounds.w = bounds.h = 4;
24159 
24160  color = g->slots[slot].color;
24161  if (!(layout->flags & NK_WINDOW_ROM) &&
24162  NK_INBOX(i->mouse.pos.x,i->mouse.pos.y, g->slots[slot].last.x-3, g->slots[slot].last.y-3, 6, 6)){
24163  ret = nk_input_is_mouse_hovering_rect(i, bounds) ? NK_CHART_HOVERING : 0;
24164  ret |= (i->mouse.buttons[NK_BUTTON_LEFT].down &&
24166  color = g->slots[slot].highlight;
24167  }
24168  nk_fill_rect(out, bounds, 0, color);
24169  g->slots[slot].index += 1;
24170  return ret;
24171  }
24172 
24173  /* draw a line between the last data point and the new one */
24174  color = g->slots[slot].color;
24175  cur.x = g->x + (float)(step * (float)g->slots[slot].index);
24176  cur.y = (g->y + g->h) - (ratio * (float)g->h);
24177  nk_stroke_line(out, g->slots[slot].last.x, g->slots[slot].last.y, cur.x, cur.y, 1.0f, color);
24178 
24179  bounds.x = cur.x - 3;
24180  bounds.y = cur.y - 3;
24181  bounds.w = bounds.h = 6;
24182 
24183  /* user selection of current data point */
24184  if (!(layout->flags & NK_WINDOW_ROM)) {
24185  if (nk_input_is_mouse_hovering_rect(i, bounds)) {
24186  ret = NK_CHART_HOVERING;
24187  ret |= (!i->mouse.buttons[NK_BUTTON_LEFT].down &&
24189  color = g->slots[slot].highlight;
24190  }
24191  }
24192  nk_fill_rect(out, nk_rect(cur.x - 2, cur.y - 2, 4, 4), 0, color);
24193 
24194  /* save current data point position */
24195  g->slots[slot].last.x = cur.x;
24196  g->slots[slot].last.y = cur.y;
24197  g->slots[slot].index += 1;
24198  return ret;
24199 }
24201 nk_chart_push_column(const struct nk_context *ctx, struct nk_window *win,
24202  struct nk_chart *chart, float value, int slot)
24203 {
24204  struct nk_command_buffer *out = &win->buffer;
24205  const struct nk_input *in = &ctx->input;
24206  struct nk_panel *layout = win->layout;
24207 
24208  float ratio;
24209  nk_flags ret = 0;
24210  struct nk_color color;
24211  struct nk_rect item = {0,0,0,0};
24212 
24213  NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
24214  if (chart->slots[slot].index >= chart->slots[slot].count)
24215  return nk_false;
24216  if (chart->slots[slot].count) {
24217  float padding = (float)(chart->slots[slot].count-1);
24218  item.w = (chart->w - padding) / (float)(chart->slots[slot].count);
24219  }
24220 
24221  /* calculate bounds of current bar chart entry */
24222  color = chart->slots[slot].color;;
24223  item.h = chart->h * NK_ABS((value/chart->slots[slot].range));
24224  if (value >= 0) {
24225  ratio = (value + NK_ABS(chart->slots[slot].min)) / NK_ABS(chart->slots[slot].range);
24226  item.y = (chart->y + chart->h) - chart->h * ratio;
24227  } else {
24228  ratio = (value - chart->slots[slot].max) / chart->slots[slot].range;
24229  item.y = chart->y + (chart->h * NK_ABS(ratio)) - item.h;
24230  }
24231  item.x = chart->x + ((float)chart->slots[slot].index * item.w);
24232  item.x = item.x + ((float)chart->slots[slot].index);
24233 
24234  /* user chart bar selection */
24235  if (!(layout->flags & NK_WINDOW_ROM) &&
24236  NK_INBOX(in->mouse.pos.x,in->mouse.pos.y,item.x,item.y,item.w,item.h)) {
24237  ret = NK_CHART_HOVERING;
24238  ret |= (!in->mouse.buttons[NK_BUTTON_LEFT].down &&
24240  color = chart->slots[slot].highlight;
24241  }
24242  nk_fill_rect(out, item, 0, color);
24243  chart->slots[slot].index += 1;
24244  return ret;
24245 }
24247 nk_chart_push_slot(struct nk_context *ctx, float value, int slot)
24248 {
24249  nk_flags flags;
24250  struct nk_window *win;
24251 
24252  NK_ASSERT(ctx);
24253  NK_ASSERT(ctx->current);
24254  NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
24255  NK_ASSERT(slot < ctx->current->layout->chart.slot);
24256  if (!ctx || !ctx->current || slot >= NK_CHART_MAX_SLOT) return nk_false;
24257  if (slot >= ctx->current->layout->chart.slot) return nk_false;
24258 
24259  win = ctx->current;
24260  if (win->layout->chart.slot < slot) return nk_false;
24261  switch (win->layout->chart.slots[slot].type) {
24262  case NK_CHART_LINES:
24263  flags = nk_chart_push_line(ctx, win, &win->layout->chart, value, slot); break;
24264  case NK_CHART_COLUMN:
24265  flags = nk_chart_push_column(ctx, win, &win->layout->chart, value, slot); break;
24266  default:
24267  case NK_CHART_MAX:
24268  flags = 0;
24269  }
24270  return flags;
24271 }
24273 nk_chart_push(struct nk_context *ctx, float value)
24274 {
24275  return nk_chart_push_slot(ctx, value, 0);
24276 }
24277 NK_API void
24278 nk_chart_end(struct nk_context *ctx)
24279 {
24280  struct nk_window *win;
24281  struct nk_chart *chart;
24282 
24283  NK_ASSERT(ctx);
24284  NK_ASSERT(ctx->current);
24285  if (!ctx || !ctx->current)
24286  return;
24287 
24288  win = ctx->current;
24289  chart = &win->layout->chart;
24290  NK_MEMSET(chart, 0, sizeof(*chart));
24291  return;
24292 }
24293 NK_API void
24294 nk_plot(struct nk_context *ctx, enum nk_chart_type type, const float *values,
24295  int count, int offset)
24296 {
24297  int i = 0;
24298  float min_value;
24299  float max_value;
24300 
24301  NK_ASSERT(ctx);
24302  NK_ASSERT(values);
24303  if (!ctx || !values || !count) return;
24304 
24305  min_value = values[offset];
24306  max_value = values[offset];
24307  for (i = 0; i < count; ++i) {
24308  min_value = NK_MIN(values[i + offset], min_value);
24309  max_value = NK_MAX(values[i + offset], max_value);
24310  }
24311 
24312  if (nk_chart_begin(ctx, type, count, min_value, max_value)) {
24313  for (i = 0; i < count; ++i)
24314  nk_chart_push(ctx, values[i + offset]);
24315  nk_chart_end(ctx);
24316  }
24317 }
24318 NK_API void
24319 nk_plot_function(struct nk_context *ctx, enum nk_chart_type type, void *userdata,
24320  float(*value_getter)(void* user, int index), int count, int offset)
24321 {
24322  int i = 0;
24323  float min_value;
24324  float max_value;
24325 
24326  NK_ASSERT(ctx);
24327  NK_ASSERT(value_getter);
24328  if (!ctx || !value_getter || !count) return;
24329 
24330  max_value = min_value = value_getter(userdata, offset);
24331  for (i = 0; i < count; ++i) {
24332  float value = value_getter(userdata, i + offset);
24333  min_value = NK_MIN(value, min_value);
24334  max_value = NK_MAX(value, max_value);
24335  }
24336 
24337  if (nk_chart_begin(ctx, type, count, min_value, max_value)) {
24338  for (i = 0; i < count; ++i)
24339  nk_chart_push(ctx, value_getter(userdata, i + offset));
24340  nk_chart_end(ctx);
24341  }
24342 }
24343 
24344 
24345 
24346 
24347 
24348 /* ==============================================================
24349  *
24350  * COLOR PICKER
24351  *
24352  * ===============================================================*/
24353 NK_LIB int
24354 nk_color_picker_behavior(nk_flags *state,
24355  const struct nk_rect *bounds, const struct nk_rect *matrix,
24356  const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar,
24357  struct nk_colorf *color, const struct nk_input *in)
24358 {
24359  float hsva[4];
24360  int value_changed = 0;
24361  int hsv_changed = 0;
24362 
24363  NK_ASSERT(state);
24364  NK_ASSERT(matrix);
24365  NK_ASSERT(hue_bar);
24366  NK_ASSERT(color);
24367 
24368  /* color matrix */
24369  nk_colorf_hsva_fv(hsva, *color);
24370  if (nk_button_behavior(state, *matrix, in, NK_BUTTON_REPEATER)) {
24371  hsva[1] = NK_SATURATE((in->mouse.pos.x - matrix->x) / (matrix->w-1));
24372  hsva[2] = 1.0f - NK_SATURATE((in->mouse.pos.y - matrix->y) / (matrix->h-1));
24373  value_changed = hsv_changed = 1;
24374  }
24375  /* hue bar */
24376  if (nk_button_behavior(state, *hue_bar, in, NK_BUTTON_REPEATER)) {
24377  hsva[0] = NK_SATURATE((in->mouse.pos.y - hue_bar->y) / (hue_bar->h-1));
24378  value_changed = hsv_changed = 1;
24379  }
24380  /* alpha bar */
24381  if (alpha_bar) {
24382  if (nk_button_behavior(state, *alpha_bar, in, NK_BUTTON_REPEATER)) {
24383  hsva[3] = 1.0f - NK_SATURATE((in->mouse.pos.y - alpha_bar->y) / (alpha_bar->h-1));
24384  value_changed = 1;
24385  }
24386  }
24387  nk_widget_state_reset(state);
24388  if (hsv_changed) {
24389  *color = nk_hsva_colorfv(hsva);
24390  *state = NK_WIDGET_STATE_ACTIVE;
24391  }
24392  if (value_changed) {
24393  color->a = hsva[3];
24394  *state = NK_WIDGET_STATE_ACTIVE;
24395  }
24396  /* set color picker widget state */
24397  if (nk_input_is_mouse_hovering_rect(in, *bounds))
24398  *state = NK_WIDGET_STATE_HOVERED;
24399  if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, *bounds))
24400  *state |= NK_WIDGET_STATE_ENTERED;
24401  else if (nk_input_is_mouse_prev_hovering_rect(in, *bounds))
24402  *state |= NK_WIDGET_STATE_LEFT;
24403  return value_changed;
24404 }
24405 NK_LIB void
24406 nk_draw_color_picker(struct nk_command_buffer *o, const struct nk_rect *matrix,
24407  const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar,
24408  struct nk_colorf col)
24409 {
24410  NK_STORAGE const struct nk_color black = {0,0,0,255};
24411  NK_STORAGE const struct nk_color white = {255, 255, 255, 255};
24412  NK_STORAGE const struct nk_color black_trans = {0,0,0,0};
24413 
24414  const float crosshair_size = 7.0f;
24415  struct nk_color temp;
24416  float hsva[4];
24417  float line_y;
24418  int i;
24419 
24420  NK_ASSERT(o);
24421  NK_ASSERT(matrix);
24422  NK_ASSERT(hue_bar);
24423 
24424  /* draw hue bar */
24425  nk_colorf_hsva_fv(hsva, col);
24426  for (i = 0; i < 6; ++i) {
24427  NK_GLOBAL const struct nk_color hue_colors[] = {
24428  {255, 0, 0, 255}, {255,255,0,255}, {0,255,0,255}, {0, 255,255,255},
24429  {0,0,255,255}, {255, 0, 255, 255}, {255, 0, 0, 255}
24430  };
24432  nk_rect(hue_bar->x, hue_bar->y + (float)i * (hue_bar->h/6.0f) + 0.5f,
24433  hue_bar->w, (hue_bar->h/6.0f) + 0.5f), hue_colors[i], hue_colors[i],
24434  hue_colors[i+1], hue_colors[i+1]);
24435  }
24436  line_y = (float)(int)(hue_bar->y + hsva[0] * matrix->h + 0.5f);
24437  nk_stroke_line(o, hue_bar->x-1, line_y, hue_bar->x + hue_bar->w + 2,
24438  line_y, 1, nk_rgb(255,255,255));
24439 
24440  /* draw alpha bar */
24441  if (alpha_bar) {
24442  float alpha = NK_SATURATE(col.a);
24443  line_y = (float)(int)(alpha_bar->y + (1.0f - alpha) * matrix->h + 0.5f);
24444 
24445  nk_fill_rect_multi_color(o, *alpha_bar, white, white, black, black);
24446  nk_stroke_line(o, alpha_bar->x-1, line_y, alpha_bar->x + alpha_bar->w + 2,
24447  line_y, 1, nk_rgb(255,255,255));
24448  }
24449 
24450  /* draw color matrix */
24451  temp = nk_hsv_f(hsva[0], 1.0f, 1.0f);
24452  nk_fill_rect_multi_color(o, *matrix, white, temp, temp, white);
24453  nk_fill_rect_multi_color(o, *matrix, black_trans, black_trans, black, black);
24454 
24455  /* draw cross-hair */
24456  {struct nk_vec2 p; float S = hsva[1]; float V = hsva[2];
24457  p.x = (float)(int)(matrix->x + S * matrix->w);
24458  p.y = (float)(int)(matrix->y + (1.0f - V) * matrix->h);
24459  nk_stroke_line(o, p.x - crosshair_size, p.y, p.x-2, p.y, 1.0f, white);
24460  nk_stroke_line(o, p.x + crosshair_size + 1, p.y, p.x+3, p.y, 1.0f, white);
24461  nk_stroke_line(o, p.x, p.y + crosshair_size + 1, p.x, p.y+3, 1.0f, white);
24462  nk_stroke_line(o, p.x, p.y - crosshair_size, p.x, p.y-2, 1.0f, white);}
24463 }
24464 NK_LIB int
24465 nk_do_color_picker(nk_flags *state,
24466  struct nk_command_buffer *out, struct nk_colorf *col,
24467  enum nk_color_format fmt, struct nk_rect bounds,
24468  struct nk_vec2 padding, const struct nk_input *in,
24469  const struct nk_user_font *font)
24470 {
24471  int ret = 0;
24472  struct nk_rect matrix;
24473  struct nk_rect hue_bar;
24474  struct nk_rect alpha_bar;
24475  float bar_w;
24476 
24477  NK_ASSERT(out);
24478  NK_ASSERT(col);
24479  NK_ASSERT(state);
24480  NK_ASSERT(font);
24481  if (!out || !col || !state || !font)
24482  return ret;
24483 
24484  bar_w = font->height;
24485  bounds.x += padding.x;
24486  bounds.y += padding.x;
24487  bounds.w -= 2 * padding.x;
24488  bounds.h -= 2 * padding.y;
24489 
24490  matrix.x = bounds.x;
24491  matrix.y = bounds.y;
24492  matrix.h = bounds.h;
24493  matrix.w = bounds.w - (3 * padding.x + 2 * bar_w);
24494 
24495  hue_bar.w = bar_w;
24496  hue_bar.y = bounds.y;
24497  hue_bar.h = matrix.h;
24498  hue_bar.x = matrix.x + matrix.w + padding.x;
24499 
24500  alpha_bar.x = hue_bar.x + hue_bar.w + padding.x;
24501  alpha_bar.y = bounds.y;
24502  alpha_bar.w = bar_w;
24503  alpha_bar.h = matrix.h;
24504 
24505  ret = nk_color_picker_behavior(state, &bounds, &matrix, &hue_bar,
24506  (fmt == NK_RGBA) ? &alpha_bar:0, col, in);
24507  nk_draw_color_picker(out, &matrix, &hue_bar, (fmt == NK_RGBA) ? &alpha_bar:0, *col);
24508  return ret;
24509 }
24510 NK_API int
24511 nk_color_pick(struct nk_context * ctx, struct nk_colorf *color,
24512  enum nk_color_format fmt)
24513 {
24514  struct nk_window *win;
24515  struct nk_panel *layout;
24516  const struct nk_style *config;
24517  const struct nk_input *in;
24518 
24519  enum nk_widget_layout_states state;
24520  struct nk_rect bounds;
24521 
24522  NK_ASSERT(ctx);
24523  NK_ASSERT(color);
24524  NK_ASSERT(ctx->current);
24525  NK_ASSERT(ctx->current->layout);
24526  if (!ctx || !ctx->current || !ctx->current->layout || !color)
24527  return 0;
24528 
24529  win = ctx->current;
24530  config = &ctx->style;
24531  layout = win->layout;
24532  state = nk_widget(&bounds, ctx);
24533  if (!state) return 0;
24534  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
24535  return nk_do_color_picker(&ctx->last_widget_state, &win->buffer, color, fmt, bounds,
24536  nk_vec2(0,0), in, config->font);
24537 }
24538 NK_API struct nk_colorf
24539 nk_color_picker(struct nk_context *ctx, struct nk_colorf color,
24540  enum nk_color_format fmt)
24541 {
24542  nk_color_pick(ctx, &color, fmt);
24543  return color;
24544 }
24545 
24546 
24547 
24548 
24549 
24550 /* ==============================================================
24551  *
24552  * COMBO
24553  *
24554  * ===============================================================*/
24555 NK_INTERN int
24556 nk_combo_begin(struct nk_context *ctx, struct nk_window *win,
24557  struct nk_vec2 size, int is_clicked, struct nk_rect header)
24558 {
24559  struct nk_window *popup;
24560  int is_open = 0;
24561  int is_active = 0;
24562  struct nk_rect body;
24563  nk_hash hash;
24564 
24565  NK_ASSERT(ctx);
24566  NK_ASSERT(ctx->current);
24567  NK_ASSERT(ctx->current->layout);
24568  if (!ctx || !ctx->current || !ctx->current->layout)
24569  return 0;
24570 
24571  popup = win->popup.win;
24572  body.x = header.x;
24573  body.w = size.x;
24574  body.y = header.y + header.h-ctx->style.window.combo_border;
24575  body.h = size.y;
24576 
24577  hash = win->popup.combo_count++;
24578  is_open = (popup) ? nk_true:nk_false;
24579  is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_COMBO);
24580  if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
24581  (!is_open && !is_active && !is_clicked)) return 0;
24582  if (!nk_nonblock_begin(ctx, 0, body,
24583  (is_clicked && is_open)?nk_rect(0,0,0,0):header, NK_PANEL_COMBO)) return 0;
24584 
24585  win->popup.type = NK_PANEL_COMBO;
24586  win->popup.name = hash;
24587  return 1;
24588 }
24589 NK_API int
24590 nk_combo_begin_text(struct nk_context *ctx, const char *selected, int len,
24591  struct nk_vec2 size)
24592 {
24593  const struct nk_input *in;
24594  struct nk_window *win;
24595  struct nk_style *style;
24596 
24597  enum nk_widget_layout_states s;
24598  int is_clicked = nk_false;
24599  struct nk_rect header;
24600  const struct nk_style_item *background;
24601  struct nk_text text;
24602 
24603  NK_ASSERT(ctx);
24604  NK_ASSERT(selected);
24605  NK_ASSERT(ctx->current);
24606  NK_ASSERT(ctx->current->layout);
24607  if (!ctx || !ctx->current || !ctx->current->layout || !selected)
24608  return 0;
24609 
24610  win = ctx->current;
24611  style = &ctx->style;
24612  s = nk_widget(&header, ctx);
24613  if (s == NK_WIDGET_INVALID)
24614  return 0;
24615 
24616  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
24618  is_clicked = nk_true;
24619 
24620  /* draw combo box header background and border */
24622  background = &style->combo.active;
24623  text.text = style->combo.label_active;
24625  background = &style->combo.hover;
24626  text.text = style->combo.label_hover;
24627  } else {
24628  background = &style->combo.normal;
24629  text.text = style->combo.label_normal;
24630  }
24631  if (background->type == NK_STYLE_ITEM_IMAGE) {
24632  text.background = nk_rgba(0,0,0,0);
24633  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
24634  } else {
24635  text.background = background->data.color;
24636  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
24637  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
24638  }
24639  {
24640  /* print currently selected text item */
24641  struct nk_rect label;
24642  struct nk_rect button;
24643  struct nk_rect content;
24644 
24645  enum nk_symbol_type sym;
24647  sym = style->combo.sym_hover;
24648  else if (is_clicked)
24649  sym = style->combo.sym_active;
24650  else sym = style->combo.sym_normal;
24651 
24652  /* calculate button */
24653  button.w = header.h - 2 * style->combo.button_padding.y;
24654  button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
24655  button.y = header.y + style->combo.button_padding.y;
24656  button.h = button.w;
24657 
24658  content.x = button.x + style->combo.button.padding.x;
24659  content.y = button.y + style->combo.button.padding.y;
24660  content.w = button.w - 2 * style->combo.button.padding.x;
24661  content.h = button.h - 2 * style->combo.button.padding.y;
24662 
24663  /* draw selected label */
24664  text.padding = nk_vec2(0,0);
24665  label.x = header.x + style->combo.content_padding.x;
24666  label.y = header.y + style->combo.content_padding.y;
24667  label.w = button.x - (style->combo.content_padding.x + style->combo.spacing.x) - label.x;;
24668  label.h = header.h - 2 * style->combo.content_padding.y;
24669  nk_widget_text(&win->buffer, label, selected, len, &text,
24671 
24672  /* draw open/close button */
24673  nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
24674  &ctx->style.combo.button, sym, style->font);
24675  }
24676  return nk_combo_begin(ctx, win, size, is_clicked, header);
24677 }
24678 NK_API int
24679 nk_combo_begin_label(struct nk_context *ctx, const char *selected, struct nk_vec2 size)
24680 {
24681  return nk_combo_begin_text(ctx, selected, nk_strlen(selected), size);
24682 }
24683 NK_API int
24684 nk_combo_begin_color(struct nk_context *ctx, struct nk_color color, struct nk_vec2 size)
24685 {
24686  struct nk_window *win;
24687  struct nk_style *style;
24688  const struct nk_input *in;
24689 
24690  struct nk_rect header;
24691  int is_clicked = nk_false;
24692  enum nk_widget_layout_states s;
24693  const struct nk_style_item *background;
24694 
24695  NK_ASSERT(ctx);
24696  NK_ASSERT(ctx->current);
24697  NK_ASSERT(ctx->current->layout);
24698  if (!ctx || !ctx->current || !ctx->current->layout)
24699  return 0;
24700 
24701  win = ctx->current;
24702  style = &ctx->style;
24703  s = nk_widget(&header, ctx);
24704  if (s == NK_WIDGET_INVALID)
24705  return 0;
24706 
24707  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
24709  is_clicked = nk_true;
24710 
24711  /* draw combo box header background and border */
24713  background = &style->combo.active;
24715  background = &style->combo.hover;
24716  else background = &style->combo.normal;
24717 
24718  if (background->type == NK_STYLE_ITEM_IMAGE) {
24719  nk_draw_image(&win->buffer, header, &background->data.image,nk_white);
24720  } else {
24721  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
24722  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
24723  }
24724  {
24725  struct nk_rect content;
24726  struct nk_rect button;
24727  struct nk_rect bounds;
24728 
24729  enum nk_symbol_type sym;
24731  sym = style->combo.sym_hover;
24732  else if (is_clicked)
24733  sym = style->combo.sym_active;
24734  else sym = style->combo.sym_normal;
24735 
24736  /* calculate button */
24737  button.w = header.h - 2 * style->combo.button_padding.y;
24738  button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
24739  button.y = header.y + style->combo.button_padding.y;
24740  button.h = button.w;
24741 
24742  content.x = button.x + style->combo.button.padding.x;
24743  content.y = button.y + style->combo.button.padding.y;
24744  content.w = button.w - 2 * style->combo.button.padding.x;
24745  content.h = button.h - 2 * style->combo.button.padding.y;
24746 
24747  /* draw color */
24748  bounds.h = header.h - 4 * style->combo.content_padding.y;
24749  bounds.y = header.y + 2 * style->combo.content_padding.y;
24750  bounds.x = header.x + 2 * style->combo.content_padding.x;
24751  bounds.w = (button.x - (style->combo.content_padding.x + style->combo.spacing.x)) - bounds.x;
24752  nk_fill_rect(&win->buffer, bounds, 0, color);
24753 
24754  /* draw open/close button */
24755  nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
24756  &ctx->style.combo.button, sym, style->font);
24757  }
24758  return nk_combo_begin(ctx, win, size, is_clicked, header);
24759 }
24760 NK_API int
24761 nk_combo_begin_symbol(struct nk_context *ctx, enum nk_symbol_type symbol, struct nk_vec2 size)
24762 {
24763  struct nk_window *win;
24764  struct nk_style *style;
24765  const struct nk_input *in;
24766 
24767  struct nk_rect header;
24768  int is_clicked = nk_false;
24769  enum nk_widget_layout_states s;
24770  const struct nk_style_item *background;
24771  struct nk_color sym_background;
24772  struct nk_color symbol_color;
24773 
24774  NK_ASSERT(ctx);
24775  NK_ASSERT(ctx->current);
24776  NK_ASSERT(ctx->current->layout);
24777  if (!ctx || !ctx->current || !ctx->current->layout)
24778  return 0;
24779 
24780  win = ctx->current;
24781  style = &ctx->style;
24782  s = nk_widget(&header, ctx);
24783  if (s == NK_WIDGET_INVALID)
24784  return 0;
24785 
24786  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
24788  is_clicked = nk_true;
24789 
24790  /* draw combo box header background and border */
24792  background = &style->combo.active;
24793  symbol_color = style->combo.symbol_active;
24795  background = &style->combo.hover;
24796  symbol_color = style->combo.symbol_hover;
24797  } else {
24798  background = &style->combo.normal;
24799  symbol_color = style->combo.symbol_hover;
24800  }
24801 
24802  if (background->type == NK_STYLE_ITEM_IMAGE) {
24803  sym_background = nk_rgba(0,0,0,0);
24804  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
24805  } else {
24806  sym_background = background->data.color;
24807  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
24808  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
24809  }
24810  {
24811  struct nk_rect bounds = {0,0,0,0};
24812  struct nk_rect content;
24813  struct nk_rect button;
24814 
24815  enum nk_symbol_type sym;
24817  sym = style->combo.sym_hover;
24818  else if (is_clicked)
24819  sym = style->combo.sym_active;
24820  else sym = style->combo.sym_normal;
24821 
24822  /* calculate button */
24823  button.w = header.h - 2 * style->combo.button_padding.y;
24824  button.x = (header.x + header.w - header.h) - style->combo.button_padding.y;
24825  button.y = header.y + style->combo.button_padding.y;
24826  button.h = button.w;
24827 
24828  content.x = button.x + style->combo.button.padding.x;
24829  content.y = button.y + style->combo.button.padding.y;
24830  content.w = button.w - 2 * style->combo.button.padding.x;
24831  content.h = button.h - 2 * style->combo.button.padding.y;
24832 
24833  /* draw symbol */
24834  bounds.h = header.h - 2 * style->combo.content_padding.y;
24835  bounds.y = header.y + style->combo.content_padding.y;
24836  bounds.x = header.x + style->combo.content_padding.x;
24837  bounds.w = (button.x - style->combo.content_padding.y) - bounds.x;
24838  nk_draw_symbol(&win->buffer, symbol, bounds, sym_background, symbol_color,
24839  1.0f, style->font);
24840 
24841  /* draw open/close button */
24842  nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state,
24843  &ctx->style.combo.button, sym, style->font);
24844  }
24845  return nk_combo_begin(ctx, win, size, is_clicked, header);
24846 }
24847 NK_API int
24848 nk_combo_begin_symbol_text(struct nk_context *ctx, const char *selected, int len,
24849  enum nk_symbol_type symbol, struct nk_vec2 size)
24850 {
24851  struct nk_window *win;
24852  struct nk_style *style;
24853  struct nk_input *in;
24854 
24855  struct nk_rect header;
24856  int is_clicked = nk_false;
24857  enum nk_widget_layout_states s;
24858  const struct nk_style_item *background;
24859  struct nk_color symbol_color;
24860  struct nk_text text;
24861 
24862  NK_ASSERT(ctx);
24863  NK_ASSERT(ctx->current);
24864  NK_ASSERT(ctx->current->layout);
24865  if (!ctx || !ctx->current || !ctx->current->layout)
24866  return 0;
24867 
24868  win = ctx->current;
24869  style = &ctx->style;
24870  s = nk_widget(&header, ctx);
24871  if (!s) return 0;
24872 
24873  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
24875  is_clicked = nk_true;
24876 
24877  /* draw combo box header background and border */
24879  background = &style->combo.active;
24880  symbol_color = style->combo.symbol_active;
24881  text.text = style->combo.label_active;
24883  background = &style->combo.hover;
24884  symbol_color = style->combo.symbol_hover;
24885  text.text = style->combo.label_hover;
24886  } else {
24887  background = &style->combo.normal;
24888  symbol_color = style->combo.symbol_normal;
24889  text.text = style->combo.label_normal;
24890  }
24891  if (background->type == NK_STYLE_ITEM_IMAGE) {
24892  text.background = nk_rgba(0,0,0,0);
24893  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
24894  } else {
24895  text.background = background->data.color;
24896  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
24897  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
24898  }
24899  {
24900  struct nk_rect content;
24901  struct nk_rect button;
24902  struct nk_rect label;
24903  struct nk_rect image;
24904 
24905  enum nk_symbol_type sym;
24907  sym = style->combo.sym_hover;
24908  else if (is_clicked)
24909  sym = style->combo.sym_active;
24910  else sym = style->combo.sym_normal;
24911 
24912  /* calculate button */
24913  button.w = header.h - 2 * style->combo.button_padding.y;
24914  button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
24915  button.y = header.y + style->combo.button_padding.y;
24916  button.h = button.w;
24917 
24918  content.x = button.x + style->combo.button.padding.x;
24919  content.y = button.y + style->combo.button.padding.y;
24920  content.w = button.w - 2 * style->combo.button.padding.x;
24921  content.h = button.h - 2 * style->combo.button.padding.y;
24922  nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
24923  &ctx->style.combo.button, sym, style->font);
24924 
24925  /* draw symbol */
24926  image.x = header.x + style->combo.content_padding.x;
24927  image.y = header.y + style->combo.content_padding.y;
24928  image.h = header.h - 2 * style->combo.content_padding.y;
24929  image.w = image.h;
24930  nk_draw_symbol(&win->buffer, symbol, image, text.background, symbol_color,
24931  1.0f, style->font);
24932 
24933  /* draw label */
24934  text.padding = nk_vec2(0,0);
24935  label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x;
24936  label.y = header.y + style->combo.content_padding.y;
24937  label.w = (button.x - style->combo.content_padding.x) - label.x;
24938  label.h = header.h - 2 * style->combo.content_padding.y;
24939  nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font);
24940  }
24941  return nk_combo_begin(ctx, win, size, is_clicked, header);
24942 }
24943 NK_API int
24944 nk_combo_begin_image(struct nk_context *ctx, struct nk_image img, struct nk_vec2 size)
24945 {
24946  struct nk_window *win;
24947  struct nk_style *style;
24948  const struct nk_input *in;
24949 
24950  struct nk_rect header;
24951  int is_clicked = nk_false;
24952  enum nk_widget_layout_states s;
24953  const struct nk_style_item *background;
24954 
24955  NK_ASSERT(ctx);
24956  NK_ASSERT(ctx->current);
24957  NK_ASSERT(ctx->current->layout);
24958  if (!ctx || !ctx->current || !ctx->current->layout)
24959  return 0;
24960 
24961  win = ctx->current;
24962  style = &ctx->style;
24963  s = nk_widget(&header, ctx);
24964  if (s == NK_WIDGET_INVALID)
24965  return 0;
24966 
24967  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
24969  is_clicked = nk_true;
24970 
24971  /* draw combo box header background and border */
24973  background = &style->combo.active;
24975  background = &style->combo.hover;
24976  else background = &style->combo.normal;
24977 
24978  if (background->type == NK_STYLE_ITEM_IMAGE) {
24979  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
24980  } else {
24981  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
24982  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
24983  }
24984  {
24985  struct nk_rect bounds = {0,0,0,0};
24986  struct nk_rect content;
24987  struct nk_rect button;
24988 
24989  enum nk_symbol_type sym;
24991  sym = style->combo.sym_hover;
24992  else if (is_clicked)
24993  sym = style->combo.sym_active;
24994  else sym = style->combo.sym_normal;
24995 
24996  /* calculate button */
24997  button.w = header.h - 2 * style->combo.button_padding.y;
24998  button.x = (header.x + header.w - header.h) - style->combo.button_padding.y;
24999  button.y = header.y + style->combo.button_padding.y;
25000  button.h = button.w;
25001 
25002  content.x = button.x + style->combo.button.padding.x;
25003  content.y = button.y + style->combo.button.padding.y;
25004  content.w = button.w - 2 * style->combo.button.padding.x;
25005  content.h = button.h - 2 * style->combo.button.padding.y;
25006 
25007  /* draw image */
25008  bounds.h = header.h - 2 * style->combo.content_padding.y;
25009  bounds.y = header.y + style->combo.content_padding.y;
25010  bounds.x = header.x + style->combo.content_padding.x;
25011  bounds.w = (button.x - style->combo.content_padding.y) - bounds.x;
25012  nk_draw_image(&win->buffer, bounds, &img, nk_white);
25013 
25014  /* draw open/close button */
25015  nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state,
25016  &ctx->style.combo.button, sym, style->font);
25017  }
25018  return nk_combo_begin(ctx, win, size, is_clicked, header);
25019 }
25020 NK_API int
25021 nk_combo_begin_image_text(struct nk_context *ctx, const char *selected, int len,
25022  struct nk_image img, struct nk_vec2 size)
25023 {
25024  struct nk_window *win;
25025  struct nk_style *style;
25026  struct nk_input *in;
25027 
25028  struct nk_rect header;
25029  int is_clicked = nk_false;
25030  enum nk_widget_layout_states s;
25031  const struct nk_style_item *background;
25032  struct nk_text text;
25033 
25034  NK_ASSERT(ctx);
25035  NK_ASSERT(ctx->current);
25036  NK_ASSERT(ctx->current->layout);
25037  if (!ctx || !ctx->current || !ctx->current->layout)
25038  return 0;
25039 
25040  win = ctx->current;
25041  style = &ctx->style;
25042  s = nk_widget(&header, ctx);
25043  if (!s) return 0;
25044 
25045  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
25047  is_clicked = nk_true;
25048 
25049  /* draw combo box header background and border */
25051  background = &style->combo.active;
25052  text.text = style->combo.label_active;
25054  background = &style->combo.hover;
25055  text.text = style->combo.label_hover;
25056  } else {
25057  background = &style->combo.normal;
25058  text.text = style->combo.label_normal;
25059  }
25060  if (background->type == NK_STYLE_ITEM_IMAGE) {
25061  text.background = nk_rgba(0,0,0,0);
25062  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
25063  } else {
25064  text.background = background->data.color;
25065  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
25066  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
25067  }
25068  {
25069  struct nk_rect content;
25070  struct nk_rect button;
25071  struct nk_rect label;
25072  struct nk_rect image;
25073 
25074  enum nk_symbol_type sym;
25076  sym = style->combo.sym_hover;
25077  else if (is_clicked)
25078  sym = style->combo.sym_active;
25079  else sym = style->combo.sym_normal;
25080 
25081  /* calculate button */
25082  button.w = header.h - 2 * style->combo.button_padding.y;
25083  button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
25084  button.y = header.y + style->combo.button_padding.y;
25085  button.h = button.w;
25086 
25087  content.x = button.x + style->combo.button.padding.x;
25088  content.y = button.y + style->combo.button.padding.y;
25089  content.w = button.w - 2 * style->combo.button.padding.x;
25090  content.h = button.h - 2 * style->combo.button.padding.y;
25091  nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
25092  &ctx->style.combo.button, sym, style->font);
25093 
25094  /* draw image */
25095  image.x = header.x + style->combo.content_padding.x;
25096  image.y = header.y + style->combo.content_padding.y;
25097  image.h = header.h - 2 * style->combo.content_padding.y;
25098  image.w = image.h;
25099  nk_draw_image(&win->buffer, image, &img, nk_white);
25100 
25101  /* draw label */
25102  text.padding = nk_vec2(0,0);
25103  label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x;
25104  label.y = header.y + style->combo.content_padding.y;
25105  label.w = (button.x - style->combo.content_padding.x) - label.x;
25106  label.h = header.h - 2 * style->combo.content_padding.y;
25107  nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font);
25108  }
25109  return nk_combo_begin(ctx, win, size, is_clicked, header);
25110 }
25111 NK_API int
25113  const char *selected, enum nk_symbol_type type, struct nk_vec2 size)
25114 {
25115  return nk_combo_begin_symbol_text(ctx, selected, nk_strlen(selected), type, size);
25116 }
25117 NK_API int
25119  const char *selected, struct nk_image img, struct nk_vec2 size)
25120 {
25121  return nk_combo_begin_image_text(ctx, selected, nk_strlen(selected), img, size);
25122 }
25123 NK_API int
25124 nk_combo_item_text(struct nk_context *ctx, const char *text, int len,nk_flags align)
25125 {
25126  return nk_contextual_item_text(ctx, text, len, align);
25127 }
25128 NK_API int
25129 nk_combo_item_label(struct nk_context *ctx, const char *label, nk_flags align)
25130 {
25131  return nk_contextual_item_label(ctx, label, align);
25132 }
25133 NK_API int
25134 nk_combo_item_image_text(struct nk_context *ctx, struct nk_image img, const char *text,
25135  int len, nk_flags alignment)
25136 {
25137  return nk_contextual_item_image_text(ctx, img, text, len, alignment);
25138 }
25139 NK_API int
25140 nk_combo_item_image_label(struct nk_context *ctx, struct nk_image img,
25141  const char *text, nk_flags alignment)
25142 {
25143  return nk_contextual_item_image_label(ctx, img, text, alignment);
25144 }
25145 NK_API int
25147  const char *text, int len, nk_flags alignment)
25148 {
25149  return nk_contextual_item_symbol_text(ctx, sym, text, len, alignment);
25150 }
25151 NK_API int
25153  const char *label, nk_flags alignment)
25154 {
25155  return nk_contextual_item_symbol_label(ctx, sym, label, alignment);
25156 }
25157 NK_API void nk_combo_end(struct nk_context *ctx)
25158 {
25160 }
25161 NK_API void nk_combo_close(struct nk_context *ctx)
25162 {
25164 }
25165 NK_API int
25166 nk_combo(struct nk_context *ctx, const char **items, int count,
25167  int selected, int item_height, struct nk_vec2 size)
25168 {
25169  int i = 0;
25170  int max_height;
25171  struct nk_vec2 item_spacing;
25172  struct nk_vec2 window_padding;
25173 
25174  NK_ASSERT(ctx);
25175  NK_ASSERT(items);
25176  NK_ASSERT(ctx->current);
25177  if (!ctx || !items ||!count)
25178  return selected;
25179 
25180  item_spacing = ctx->style.window.spacing;
25181  window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
25182  max_height = count * item_height + count * (int)item_spacing.y;
25183  max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
25184  size.y = NK_MIN(size.y, (float)max_height);
25185  if (nk_combo_begin_label(ctx, items[selected], size)) {
25186  nk_layout_row_dynamic(ctx, (float)item_height, 1);
25187  for (i = 0; i < count; ++i) {
25188  if (nk_combo_item_label(ctx, items[i], NK_TEXT_LEFT))
25189  selected = i;
25190  }
25191  nk_combo_end(ctx);
25192  }
25193  return selected;
25194 }
25195 NK_API int
25196 nk_combo_separator(struct nk_context *ctx, const char *items_separated_by_separator,
25197  int separator, int selected, int count, int item_height, struct nk_vec2 size)
25198 {
25199  int i;
25200  int max_height;
25201  struct nk_vec2 item_spacing;
25202  struct nk_vec2 window_padding;
25203  const char *current_item;
25204  const char *iter;
25205  int length = 0;
25206 
25207  NK_ASSERT(ctx);
25208  NK_ASSERT(items_separated_by_separator);
25209  if (!ctx || !items_separated_by_separator)
25210  return selected;
25211 
25212  /* calculate popup window */
25213  item_spacing = ctx->style.window.spacing;
25214  window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
25215  max_height = count * item_height + count * (int)item_spacing.y;
25216  max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
25217  size.y = NK_MIN(size.y, (float)max_height);
25218 
25219  /* find selected item */
25220  current_item = items_separated_by_separator;
25221  for (i = 0; i < count; ++i) {
25222  iter = current_item;
25223  while (*iter && *iter != separator) iter++;
25224  length = (int)(iter - current_item);
25225  if (i == selected) break;
25226  current_item = iter + 1;
25227  }
25228 
25229  if (nk_combo_begin_text(ctx, current_item, length, size)) {
25230  current_item = items_separated_by_separator;
25231  nk_layout_row_dynamic(ctx, (float)item_height, 1);
25232  for (i = 0; i < count; ++i) {
25233  iter = current_item;
25234  while (*iter && *iter != separator) iter++;
25235  length = (int)(iter - current_item);
25236  if (nk_combo_item_text(ctx, current_item, length, NK_TEXT_LEFT))
25237  selected = i;
25238  current_item = current_item + length + 1;
25239  }
25240  nk_combo_end(ctx);
25241  }
25242  return selected;
25243 }
25244 NK_API int
25245 nk_combo_string(struct nk_context *ctx, const char *items_separated_by_zeros,
25246  int selected, int count, int item_height, struct nk_vec2 size)
25247 {
25248  return nk_combo_separator(ctx, items_separated_by_zeros, '\0', selected, count, item_height, size);
25249 }
25250 NK_API int
25251 nk_combo_callback(struct nk_context *ctx, void(*item_getter)(void*, int, const char**),
25252  void *userdata, int selected, int count, int item_height, struct nk_vec2 size)
25253 {
25254  int i;
25255  int max_height;
25256  struct nk_vec2 item_spacing;
25257  struct nk_vec2 window_padding;
25258  const char *item;
25259 
25260  NK_ASSERT(ctx);
25261  NK_ASSERT(item_getter);
25262  if (!ctx || !item_getter)
25263  return selected;
25264 
25265  /* calculate popup window */
25266  item_spacing = ctx->style.window.spacing;
25267  window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
25268  max_height = count * item_height + count * (int)item_spacing.y;
25269  max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
25270  size.y = NK_MIN(size.y, (float)max_height);
25271 
25272  item_getter(userdata, selected, &item);
25273  if (nk_combo_begin_label(ctx, item, size)) {
25274  nk_layout_row_dynamic(ctx, (float)item_height, 1);
25275  for (i = 0; i < count; ++i) {
25276  item_getter(userdata, i, &item);
25277  if (nk_combo_item_label(ctx, item, NK_TEXT_LEFT))
25278  selected = i;
25279  }
25280  nk_combo_end(ctx);
25281  } return selected;
25282 }
25283 NK_API void
25284 nk_combobox(struct nk_context *ctx, const char **items, int count,
25285  int *selected, int item_height, struct nk_vec2 size)
25286 {
25287  *selected = nk_combo(ctx, items, count, *selected, item_height, size);
25288 }
25289 NK_API void
25290 nk_combobox_string(struct nk_context *ctx, const char *items_separated_by_zeros,
25291  int *selected, int count, int item_height, struct nk_vec2 size)
25292 {
25293  *selected = nk_combo_string(ctx, items_separated_by_zeros, *selected, count, item_height, size);
25294 }
25295 NK_API void
25296 nk_combobox_separator(struct nk_context *ctx, const char *items_separated_by_separator,
25297  int separator,int *selected, int count, int item_height, struct nk_vec2 size)
25298 {
25299  *selected = nk_combo_separator(ctx, items_separated_by_separator, separator,
25300  *selected, count, item_height, size);
25301 }
25302 NK_API void
25304  void(*item_getter)(void* data, int id, const char **out_text),
25305  void *userdata, int *selected, int count, int item_height, struct nk_vec2 size)
25306 {
25307  *selected = nk_combo_callback(ctx, item_getter, userdata, *selected, count, item_height, size);
25308 }
25309 
25310 
25311 
25312 
25313 
25314 /* ===============================================================
25315  *
25316  * TOOLTIP
25317  *
25318  * ===============================================================*/
25319 NK_API int
25320 nk_tooltip_begin(struct nk_context *ctx, float width)
25321 {
25322  int x,y,w,h;
25323  struct nk_window *win;
25324  const struct nk_input *in;
25325  struct nk_rect bounds;
25326  int ret;
25327 
25328  NK_ASSERT(ctx);
25329  NK_ASSERT(ctx->current);
25330  NK_ASSERT(ctx->current->layout);
25331  if (!ctx || !ctx->current || !ctx->current->layout)
25332  return 0;
25333 
25334  /* make sure that no nonblocking popup is currently active */
25335  win = ctx->current;
25336  in = &ctx->input;
25337  if (win->popup.win && (win->popup.type & NK_PANEL_SET_NONBLOCK))
25338  return 0;
25339 
25340  w = nk_iceilf(width);
25341  h = nk_iceilf(nk_null_rect.h);
25342  x = nk_ifloorf(in->mouse.pos.x + 1) - (int)win->layout->clip.x;
25343  y = nk_ifloorf(in->mouse.pos.y + 1) - (int)win->layout->clip.y;
25344 
25345  bounds.x = (float)x;
25346  bounds.y = (float)y;
25347  bounds.w = (float)w;
25348  bounds.h = (float)h;
25349 
25351  "__##Tooltip##__", NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER, bounds);
25352  if (ret) win->layout->flags &= ~(nk_flags)NK_WINDOW_ROM;
25353  win->popup.type = NK_PANEL_TOOLTIP;
25355  return ret;
25356 }
25357 
25358 NK_API void
25359 nk_tooltip_end(struct nk_context *ctx)
25360 {
25361  NK_ASSERT(ctx);
25362  NK_ASSERT(ctx->current);
25363  if (!ctx || !ctx->current) return;
25364  ctx->current->seq--;
25366  nk_popup_end(ctx);
25367 }
25368 NK_API void
25369 nk_tooltip(struct nk_context *ctx, const char *text)
25370 {
25371  const struct nk_style *style;
25372  struct nk_vec2 padding;
25373 
25374  int text_len;
25375  float text_width;
25376  float text_height;
25377 
25378  NK_ASSERT(ctx);
25379  NK_ASSERT(ctx->current);
25380  NK_ASSERT(ctx->current->layout);
25381  NK_ASSERT(text);
25382  if (!ctx || !ctx->current || !ctx->current->layout || !text)
25383  return;
25384 
25385  /* fetch configuration data */
25386  style = &ctx->style;
25387  padding = style->window.padding;
25388 
25389  /* calculate size of the text and tooltip */
25390  text_len = nk_strlen(text);
25391  text_width = style->font->width(style->font->userdata,
25392  style->font->height, text, text_len);
25393  text_width += (4 * padding.x);
25394  text_height = (style->font->height + 2 * padding.y);
25395 
25396  /* execute tooltip and fill with text */
25397  if (nk_tooltip_begin(ctx, (float)text_width)) {
25398  nk_layout_row_dynamic(ctx, (float)text_height, 1);
25399  nk_text(ctx, text, text_len, NK_TEXT_LEFT);
25401  }
25402 }
25403 #ifdef NK_INCLUDE_STANDARD_VARARGS
25404 NK_API void
25405 nk_tooltipf(struct nk_context *ctx, const char *fmt, ...)
25406 {
25407  va_list args;
25408  va_start(args, fmt);
25409  nk_tooltipfv(ctx, fmt, args);
25410  va_end(args);
25411 }
25412 NK_API void
25413 nk_tooltipfv(struct nk_context *ctx, const char *fmt, va_list args)
25414 {
25415  char buf[256];
25416  nk_strfmt(buf, NK_LEN(buf), fmt, args);
25417  nk_tooltip(ctx, buf);
25418 }
25419 #endif
25420 
25421 
25422 
25423 #endif /* NK_IMPLEMENTATION */
25424 
25425 /*
25468 
25780 */
25781 
nk_edit_state::sel_start
int sel_start
Definition: nuklear.h:5389
nk_color_hex_rgb
NK_API void nk_color_hex_rgb(char *output, struct nk_color)
NK_COMMAND_RECT
@ NK_COMMAND_RECT
Definition: nuklear.h:4380
nk_command_custom::callback_data
nk_handle callback_data
Definition: nuklear.h:4542
nk_command_clipping
nk_command_clipping
Definition: nuklear.h:4558
op
static int op
Definition: main.cpp:53
nk_rect_size
NK_API struct nk_vec2 nk_rect_size(struct nk_rect)
nk_keyboard::text_len
int text_len
Definition: nuklear.h:4623
nk_group_end
NK_API void nk_group_end(struct nk_context *)
nk_str
Definition: nuklear.h:4165
NK_INT32
#define NK_INT32
Definition: nuklear.h:357
NK_WINDOW_BORDER
@ NK_WINDOW_BORDER
Definition: nuklear.h:1452
NK_COMMAND_CIRCLE_FILLED
@ NK_COMMAND_CIRCLE_FILLED
Definition: nuklear.h:4384
NK_TEXT_ALIGN_MIDDLE
@ NK_TEXT_ALIGN_MIDDLE
Definition: nuklear.h:3078
nk_style_toggle::cursor_normal
struct nk_style_item cursor_normal
Definition: nuklear.h:4861
nk_menu_close
NK_API void nk_menu_close(struct nk_context *)
nk_memory_status::type
unsigned int type
Definition: nuklear.h:4095
nk_style_tab::border
float border
Definition: nuklear.h:5140
NK_WIDGET_ROM
@ NK_WIDGET_ROM
Definition: nuklear.h:3045
nk_style_text::color
struct nk_color color
Definition: nuklear.h:4822
nk_style_header_align
nk_style_header_align
Definition: nuklear.h:5147
NK_TEXT_ALIGN_CENTERED
@ NK_TEXT_ALIGN_CENTERED
Definition: nuklear.h:3075
nk_style_selectable::pressed_active
struct nk_style_item pressed_active
Definition: nuklear.h:4892
nk_style_property::rounding
float rounding
Definition: nuklear.h:5068
nk_command_polygon_filled::point_count
unsigned short point_count
Definition: nuklear.h:4516
nk_configuration_stacks::vectors
struct nk_config_stack_vec2 vectors
Definition: nuklear.h:5520
nk_style_window::spacing
struct nk_vec2 spacing
Definition: nuklear.h:5200
nk_command_polygon::color
struct nk_color color
Definition: nuklear.h:4507
NK_WINDOW_MINIMIZABLE
@ NK_WINDOW_MINIMIZABLE
Definition: nuklear.h:1456
nk_command_image::col
struct nk_color col
Definition: nuklear.h:4533
nk_style_pop_font
NK_API int nk_style_pop_font(struct nk_context *)
NK_RGB
@ NK_RGB
Definition: nuklear.h:478
nk_int
NK_INT32 nk_int
Definition: nuklear.h:404
nk_select_label
NK_API int nk_select_label(struct nk_context *, const char *, nk_flags align, int value)
nk_button_color
NK_API int nk_button_color(struct nk_context *, struct nk_color)
nk_pool::cap
nk_size cap
Definition: nuklear.h:5567
nk_combobox_callback
NK_API void nk_combobox_callback(struct nk_context *, void(*item_getter)(void *, int, const char **), void *, int *selected, int count, int item_height, struct nk_vec2 size)
nk_command_rect_filled::x
short x
Definition: nuklear.h:4441
nk_window_get_panel
NK_API struct nk_panel * nk_window_get_panel(struct nk_context *)
nk_style_combo::label_hover
struct nk_color label_hover
Definition: nuklear.h:5103
nk_window
Definition: nuklear.h:5409
nk_style_window::group_border
float group_border
Definition: nuklear.h:5194
NK_CONVERT_COMMAND_BUFFER_FULL
@ NK_CONVERT_COMMAND_BUFFER_FULL
Definition: nuklear.h:1147
nk_style_chart::background
struct nk_style_item background
Definition: nuklear.h:5083
nk_combo_begin_image
NK_API int nk_combo_begin_image(struct nk_context *, struct nk_image img, struct nk_vec2 size)
nk_style_progress::padding
struct nk_vec2 padding
Definition: nuklear.h:4975
nk_style_scrollbar::border
float border
Definition: nuklear.h:4997
nk_window_get_content_region_min
NK_API struct nk_vec2 nk_window_get_content_region_min(struct nk_context *)
NK_COLOR_BUTTON_HOVER
@ NK_COLOR_BUTTON_HOVER
Definition: nuklear.h:3568
nk_style_selectable::text_hover_active
struct nk_color text_hover_active
Definition: nuklear.h:4901
nk_row_layout::item_width
float item_width
Definition: nuklear.h:5304
nk_hsv_bv
NK_API struct nk_color nk_hsv_bv(const nk_byte *hsv)
nk_handle::ptr
void * ptr
Definition: nuklear.h:465
nk_image_id
NK_API struct nk_image nk_image_id(int)
nk_style_slider::inc_button
struct nk_style_button inc_button
Definition: nuklear.h:4946
nk_context::button_behavior
enum nk_button_behavior button_behavior
Definition: nuklear.h:5577
NK_KEY_CUT
@ NK_KEY_CUT
Definition: nuklear.h:745
nk_row_layout::min_height
float min_height
Definition: nuklear.h:5301
NK_ALIGN_PTR_BACK
#define NK_ALIGN_PTR_BACK(x, mask)
Definition: nuklear.h:5659
NK_EDIT_READ_ONLY
@ NK_EDIT_READ_ONLY
Definition: nuklear.h:3418
nk_command_triangle_filled::color
struct nk_color color
Definition: nuklear.h:4470
nk_color_hsv_iv
NK_API void nk_color_hsv_iv(int *hsv_out, struct nk_color)
NK_COMMAND_NOP
@ NK_COMMAND_NOP
Definition: nuklear.h:4376
NK_KEY_NONE
@ NK_KEY_NONE
Definition: nuklear.h:737
NK_CONVERT_VERTEX_BUFFER_FULL
@ NK_CONVERT_VERTEX_BUFFER_FULL
Definition: nuklear.h:1148
nk_edit_state::sel_end
int sel_end
Definition: nuklear.h:5390
nk_command_polygon::point_count
unsigned short point_count
Definition: nuklear.h:4509
nk_vec2v
NK_API struct nk_vec2 nk_vec2v(const float *xy)
nk_menu_item_label
NK_API int nk_menu_item_label(struct nk_context *, const char *, nk_flags alignment)
nk_str_init_fixed
NK_API void nk_str_init_fixed(struct nk_str *, void *memory, nk_size size)
nk_command_triangle
Definition: nuklear.h:4456
nk_command_arc_filled
Definition: nuklear.h:4497
nk_style_slider::active
struct nk_style_item active
Definition: nuklear.h:4922
nk_command_polyline::point_count
unsigned short point_count
Definition: nuklear.h:4524
nk_menu_item_text
NK_API int nk_menu_item_text(struct nk_context *, const char *, int, nk_flags align)
nk_recti
Definition: nuklear.h:463
nk_panel::menu
struct nk_menu_state menu
Definition: nuklear.h:5338
nk_command_scissor::x
short x
Definition: nuklear.h:4408
nk_command_circle
Definition: nuklear.h:4473
nk_style_slider::rounding
float rounding
Definition: nuklear.h:4938
nk_command_polygon
Definition: nuklear.h:4505
nk_edit_string_zero_terminated
NK_API nk_flags nk_edit_string_zero_terminated(struct nk_context *, nk_flags, char *buffer, int max, nk_plugin_filter)
nk_colorf
Definition: nuklear.h:459
nk_rgba_bv
NK_API struct nk_color nk_rgba_bv(const nk_byte *rgba)
NK_TEXT_EDIT_MODE_INSERT
@ NK_TEXT_EDIT_MODE_INSERT
Definition: nuklear.h:4277
nk_command_text::w
unsigned short w
Definition: nuklear.h:4552
nk_rgb_iv
NK_API struct nk_color nk_rgb_iv(const int *rgb)
nk_layout_space_rect_to_local
NK_API struct nk_rect nk_layout_space_rect_to_local(struct nk_context *, struct nk_rect)
NK_BUTTON_MIDDLE
@ NK_BUTTON_MIDDLE
Definition: nuklear.h:773
nk_style_edit::text_active
struct nk_color text_active
Definition: nuklear.h:5033
NK_COLOR_CHART_COLOR_HIGHLIGHT
@ NK_COLOR_CHART_COLOR_HIGHLIGHT
Definition: nuklear.h:3585
nk_layout_widget_bounds
NK_API struct nk_rect nk_layout_widget_bounds(struct nk_context *)
nk_chart_event
nk_chart_event
Definition: nuklear.h:477
nk_rectv
NK_API struct nk_rect nk_rectv(const float *xywh)
nk_window::edit
struct nk_edit_state edit
Definition: nuklear.h:5424
nk_memory_status::calls
nk_size calls
Definition: nuklear.h:4099
NK_CHART_MAX_SLOT
#define NK_CHART_MAX_SLOT
Definition: nuklear.h:5250
nk_command_rect::w
unsigned short w
Definition: nuklear.h:4434
nk_buffer
Definition: nuklear.h:4119
nk_command_line
Definition: nuklear.h:4412
NK_COLOR_TEXT
@ NK_COLOR_TEXT
Definition: nuklear.h:3563
nk_pool::capacity
unsigned capacity
Definition: nuklear.h:5565
nk_str_delete_chars
NK_API void nk_str_delete_chars(struct nk_str *, int pos, int len)
nk_edit_state::name
nk_hash name
Definition: nuklear.h:5384
nk_rgba_fv
NK_API struct nk_color nk_rgba_fv(const float *rgba)
nk_style_push_float
NK_API int nk_style_push_float(struct nk_context *, float *, float)
nk_combo_item_label
NK_API int nk_combo_item_label(struct nk_context *, const char *, nk_flags alignment)
nk_vec2i::x
short x
Definition: nuklear.h:461
nk_ptr
NK_POINTER_TYPE nk_ptr
Definition: nuklear.h:407
nk_byte
NK_UINT8 nk_byte
Definition: nuklear.h:401
nk_command_polygon_filled::points
struct nk_vec2i points[1]
Definition: nuklear.h:4517
nk_table
Definition: nuklear.h:5533
nk_contextual_item_image_text
NK_API int nk_contextual_item_image_text(struct nk_context *, struct nk_image, const char *, int len, nk_flags alignment)
nk_style_slider::bar_active
struct nk_color bar_active
Definition: nuklear.h:4928
nk_command_circle_filled::y
short y
Definition: nuklear.h:4483
nk_str_insert_str_utf8
NK_API int nk_str_insert_str_utf8(struct nk_str *, int pos, const char *)
nk_convert_result
nk_convert_result
Definition: nuklear.h:1144
NK_BUFFER_FIXED
@ NK_BUFFER_FIXED
Definition: nuklear.h:4103
NK_EDIT_INACTIVE
@ NK_EDIT_INACTIVE
Definition: nuklear.h:3439
nk_panel_flags
nk_panel_flags
Definition: nuklear.h:1451
nk_style::combo
struct nk_style_combo combo
Definition: nuklear.h:5235
nk_convert_config::null
struct nk_draw_null_texture null
Definition: nuklear.h:1162
NK_COLOR_SELECT_ACTIVE
@ NK_COLOR_SELECT_ACTIVE
Definition: nuklear.h:3574
NK_FONT_STACK_SIZE
#define NK_FONT_STACK_SIZE
Definition: nuklear.h:5466
nk_style_text::padding
struct nk_vec2 padding
Definition: nuklear.h:4823
nk_command_rect_filled::w
unsigned short w
Definition: nuklear.h:4442
nk_style_toggle
Definition: nuklear.h:4853
nk_rgba_u32
NK_API struct nk_color nk_rgba_u32(nk_uint)
nk_style_from_table
NK_API void nk_style_from_table(struct nk_context *, const struct nk_color *)
NK_UTF_INVALID
#define NK_UTF_INVALID
Definition: nuklear.h:5615
nk_command_text::h
unsigned short h
Definition: nuklear.h:4552
nk_input_is_key_pressed
NK_API int nk_input_is_key_pressed(const struct nk_input *, enum nk_keys)
NK_STYLE_ITEM_IMAGE
@ NK_STYLE_ITEM_IMAGE
Definition: nuklear.h:4808
nk_context::clip
struct nk_clipboard clip
Definition: nuklear.h:5575
nk_rgb_bv
NK_API struct nk_color nk_rgb_bv(const nk_byte *rgb)
nk_tree_state_push
NK_API int nk_tree_state_push(struct nk_context *, enum nk_tree_type, const char *title, enum nk_collapse_states *state)
NK_WINDOW_NO_SCROLLBAR
@ NK_WINDOW_NO_SCROLLBAR
Definition: nuklear.h:1457
nk_window_collapse
NK_API void nk_window_collapse(struct nk_context *, const char *name, enum nk_collapse_states state)
nk_style_selectable::text_pressed
struct nk_color text_pressed
Definition: nuklear.h:4897
nk_symbol_type
nk_symbol_type
Definition: nuklear.h:494
nk_textedit_select_all
NK_API void nk_textedit_select_all(struct nk_text_edit *)
nk_style_scrollbar::dec_button
struct nk_style_button dec_button
Definition: nuklear.h:5006
NK_EDIT_SELECTABLE
@ NK_EDIT_SELECTABLE
Definition: nuklear.h:3423
nk_command_rect::rounding
unsigned short rounding
Definition: nuklear.h:4431
nk_button_image_label
NK_API int nk_button_image_label(struct nk_context *, struct nk_image img, const char *, nk_flags text_alignment)
nk_popup_buffer::active
int active
Definition: nuklear.h:5318
NK_COLOR_WINDOW
@ NK_COLOR_WINDOW
Definition: nuklear.h:3564
nk_combo_item_symbol_text
NK_API int nk_combo_item_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags alignment)
nk_page::win
struct nk_page_element win[1]
Definition: nuklear.h:5556
nk_layout_row_end
NK_API void nk_layout_row_end(struct nk_context *)
nk_str_insert_at_rune
NK_API int nk_str_insert_at_rune(struct nk_str *, int pos, const char *, int)
NK_COMMAND_TRIANGLE_FILLED
@ NK_COMMAND_TRIANGLE_FILLED
Definition: nuklear.h:4388
nk_style::cursor_visible
int cursor_visible
Definition: nuklear.h:5218
nk_style_slider::dec_button
struct nk_style_button dec_button
Definition: nuklear.h:4947
nk_fill_circle
NK_API void nk_fill_circle(struct nk_command_buffer *, struct nk_rect, struct nk_color)
NK_TEXT_ALIGN_BOTTOM
@ NK_TEXT_ALIGN_BOTTOM
Definition: nuklear.h:3079
nk_command_polygon_filled::header
struct nk_command header
Definition: nuklear.h:4514
NK_TREE_TAB
@ NK_TREE_TAB
Definition: nuklear.h:481
nk_style_edit::selected_text_hover
struct nk_color selected_text_hover
Definition: nuklear.h:5039
NK_WINDOW_MINIMIZED
@ NK_WINDOW_MINIMIZED
Definition: nuklear.h:5365
nk_text_undo_record::insert_length
short insert_length
Definition: nuklear.h:4256
nk_window::property
struct nk_property_state property
Definition: nuklear.h:5422
nk_color_hsv_fv
NK_API void nk_color_hsv_fv(float *hsv_out, struct nk_color)
nk_chart::x
float x
Definition: nuklear.h:5281
nk_panel_type
nk_panel_type
Definition: nuklear.h:5253
NK_LAYOUT_DYNAMIC_ROW
@ NK_LAYOUT_DYNAMIC_ROW
Definition: nuklear.h:5287
nk_text_width_f
float(* nk_text_width_f)(nk_handle, float h, const char *, int len)
Definition: nuklear.h:3897
nk_style::scrollv
struct nk_style_scrollbar scrollv
Definition: nuklear.h:5233
nk_style_window::menu_border_color
struct nk_color menu_border_color
Definition: nuklear.h:5185
nk_property_float
NK_API void nk_property_float(struct nk_context *, const char *name, float min, float *val, float max, float step, float inc_per_pixel)
nk_widget_is_hovered
NK_API int nk_widget_is_hovered(struct nk_context *)
nk_command_buffer::userdata
nk_handle userdata
Definition: nuklear.h:4567
nk_style_window::fixed_background
struct nk_style_item fixed_background
Definition: nuklear.h:5178
nk_button_text_styled
NK_API int nk_button_text_styled(struct nk_context *, const struct nk_style_button *, const char *title, int len)
nk_style_edit::selected_hover
struct nk_color selected_hover
Definition: nuklear.h:5037
nk_stroke_circle
NK_API void nk_stroke_circle(struct nk_command_buffer *, struct nk_rect, float line_thickness, struct nk_color)
nk_command_scissor::header
struct nk_command header
Definition: nuklear.h:4407
nk_style_scrollbar::dec_symbol
enum nk_symbol_type dec_symbol
Definition: nuklear.h:5008
nk_style_combo::hover
struct nk_style_item hover
Definition: nuklear.h:5097
nk_user_font::height
float height
Definition: nuklear.h:3918
nk_command
Definition: nuklear.h:4398
NK_TEXT_EDIT_SINGLE_LINE
@ NK_TEXT_EDIT_SINGLE_LINE
Definition: nuklear.h:4271
nk_context::delta_time_seconds
float delta_time_seconds
Definition: nuklear.h:5579
NK_EDIT_DEACTIVATED
@ NK_EDIT_DEACTIVATED
Definition: nuklear.h:3441
NK_COLOR_SLIDER_CURSOR_HOVER
@ NK_COLOR_SLIDER_CURSOR_HOVER
Definition: nuklear.h:3577
nk_allocator::alloc
nk_plugin_alloc alloc
Definition: nuklear.h:491
nk_buffer::needed
nk_size needed
Definition: nuklear.h:4132
NK_WINDOW_DYNAMIC
@ NK_WINDOW_DYNAMIC
Definition: nuklear.h:5355
nk_style_progress::cursor_hover
struct nk_style_item cursor_hover
Definition: nuklear.h:4966
nk_edit_state::cursor
int cursor
Definition: nuklear.h:5388
nk_style_progress::cursor_border
float cursor_border
Definition: nuklear.h:4973
NK_WINDOW_SCROLL_AUTO_HIDE
@ NK_WINDOW_SCROLL_AUTO_HIDE
Definition: nuklear.h:1459
nk_style::property
struct nk_style_property property
Definition: nuklear.h:5229
NK_POPUP_STATIC
@ NK_POPUP_STATIC
Definition: nuklear.h:479
nk_style_window::group_padding
struct nk_vec2 group_padding
Definition: nuklear.h:5205
nk_style_window::menu_border
float menu_border
Definition: nuklear.h:5193
nk_keyboard
Definition: nuklear.h:4620
NK_KEY_TEXT_REPLACE_MODE
@ NK_KEY_TEXT_REPLACE_MODE
Definition: nuklear.h:753
nk_window_set_size
NK_API void nk_window_set_size(struct nk_context *, const char *name, struct nk_vec2)
NK_BUTTON_BEHAVIOR_STACK_SIZE
#define NK_BUTTON_BEHAVIOR_STACK_SIZE
Definition: nuklear.h:5462
nk_input_has_mouse_click_down_in_rect
NK_API int nk_input_has_mouse_click_down_in_rect(const struct nk_input *, enum nk_buttons, struct nk_rect, int down)
nk_style_edit::active
struct nk_style_item active
Definition: nuklear.h:5020
nk_mouse_button
Definition: nuklear.h:4600
NK_KEY_BACKSPACE
@ NK_KEY_BACKSPACE
Definition: nuklear.h:743
nk_vec2_muls
#define nk_vec2_muls(a, t)
Definition: nuklear.h:5633
nk_style_cursor
nk_style_cursor
Definition: nuklear.h:3593
nk_image::region
unsigned short region[4]
Definition: nuklear.h:466
nk_style_window_header::hover
struct nk_style_item hover
Definition: nuklear.h:5154
nk_style_button
Definition: nuklear.h:4826
nk_vec2iv
NK_API struct nk_vec2 nk_vec2iv(const int *xy)
nk_property_state::old
unsigned int old
Definition: nuklear.h:5405
nk_str_delete_runes
NK_API void nk_str_delete_runes(struct nk_str *, int pos, int len)
nk_combo_end
NK_API void nk_combo_end(struct nk_context *)
nk_style_scrollbar::inc_symbol
enum nk_symbol_type inc_symbol
Definition: nuklear.h:5007
nk_edit_state::scrollbar
struct nk_scroll scrollbar
Definition: nuklear.h:5391
nk_heading
nk_heading
Definition: nuklear.h:470
nk_glyph
char nk_glyph[NK_UTF_SIZE]
Definition: nuklear.h:464
nk_window_is_any_hovered
NK_API int nk_window_is_any_hovered(struct nk_context *)
nk_command_buffer::end
nk_size end
Definition: nuklear.h:4568
nk_buffer::calls
nk_size calls
Definition: nuklear.h:4134
nk_panel::offset_y
nk_uint * offset_y
Definition: nuklear.h:5331
nk_style_default
NK_API void nk_style_default(struct nk_context *)
nk_propertyi
NK_API int nk_propertyi(struct nk_context *, const char *name, int min, int val, int max, int step, float inc_per_pixel)
nk_style_window::combo_padding
struct nk_vec2 combo_padding
Definition: nuklear.h:5207
nk_strtod
NK_API double nk_strtod(const char *str, const char **endptr)
nk_layout_space_to_local
NK_API struct nk_vec2 nk_layout_space_to_local(struct nk_context *, struct nk_vec2)
nk_style_tab::rounding
float rounding
Definition: nuklear.h:5141
nk_style_toggle::userdata
nk_handle userdata
Definition: nuklear.h:4878
NK_ALIGNOF
#define NK_ALIGNOF(t)
Definition: nuklear.h:5680
nk_command_custom::h
unsigned short h
Definition: nuklear.h:4541
NK_CHART_HOVERING
@ NK_CHART_HOVERING
Definition: nuklear.h:477
nk_style_progress::userdata
nk_handle userdata
Definition: nuklear.h:4978
nk_command_polyline::header
struct nk_command header
Definition: nuklear.h:4521
nk_combo_item_text
NK_API int nk_combo_item_text(struct nk_context *, const char *, int, nk_flags alignment)
nk_command_circle_filled::header
struct nk_command header
Definition: nuklear.h:4482
nk_style_window::contextual_padding
struct nk_vec2 contextual_padding
Definition: nuklear.h:5208
nk_contextual_begin
NK_API int nk_contextual_begin(struct nk_context *, nk_flags, struct nk_vec2, struct nk_rect trigger_bounds)
nk_chart_slot::type
enum nk_chart_type type
Definition: nuklear.h:5270
nk_handle::id
int id
Definition: nuklear.h:465
nk_memory_status::needed
nk_size needed
Definition: nuklear.h:4098
nk_command_triangle::color
struct nk_color color
Definition: nuklear.h:4462
nk_command_circle::color
struct nk_color color
Definition: nuklear.h:4478
nk_command_rect_multi_color::w
unsigned short w
Definition: nuklear.h:4449
nk_style_slider::inc_symbol
enum nk_symbol_type inc_symbol
Definition: nuklear.h:4948
nk_combobox_separator
NK_API void nk_combobox_separator(struct nk_context *, const char *items_separated_by_separator, int separator, int *selected, int count, int item_height, struct nk_vec2 size)
NK_CLIPPING_OFF
@ NK_CLIPPING_OFF
Definition: nuklear.h:4559
NK_UINT32
#define NK_UINT32
Definition: nuklear.h:364
NK_SYMBOL_PLUS
@ NK_SYMBOL_PLUS
Definition: nuklear.h:506
nk_style_window::contextual_border
float contextual_border
Definition: nuklear.h:5192
nk_style_window::tooltip_border
float tooltip_border
Definition: nuklear.h:5195
nk_widget_position
NK_API struct nk_vec2 nk_widget_position(struct nk_context *)
nk_style::checkbox
struct nk_style_toggle checkbox
Definition: nuklear.h:5225
nk_input
Definition: nuklear.h:4626
nk_style_slider::border_color
struct nk_color border_color
Definition: nuklear.h:4923
nk_style_combo::sym_normal
enum nk_symbol_type sym_normal
Definition: nuklear.h:5113
nk_popup_buffer
Definition: nuklear.h:5313
nk_popup_state::name
nk_hash name
Definition: nuklear.h:5375
nk_panel::bounds
struct nk_rect bounds
Definition: nuklear.h:5329
nk_style_tab::spacing
struct nk_vec2 spacing
Definition: nuklear.h:5144
nk_style_property::draw_end
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:5078
nk_command_circle_filled::w
unsigned short w
Definition: nuklear.h:4484
nk_command_triangle_filled::c
struct nk_vec2i c
Definition: nuklear.h:4469
NK_CONFIG_STACK
#define NK_CONFIG_STACK(type, size)
Definition: nuklear.h:5494
NK_CLIPPING_ON
@ NK_CLIPPING_ON
Definition: nuklear.h:4560
NK_COLOR_CHART_COLOR
@ NK_COLOR_CHART_COLOR
Definition: nuklear.h:3584
nk_mouse::prev
struct nk_vec2 prev
Definition: nuklear.h:4608
NK_HEADER_RIGHT
@ NK_HEADER_RIGHT
Definition: nuklear.h:5149
nk_style_combo::label_normal
struct nk_color label_normal
Definition: nuklear.h:5102
nk_page_element::next
struct nk_page_element * next
Definition: nuklear.h:5549
nk_contextual_item_text
NK_API int nk_contextual_item_text(struct nk_context *, const char *, int, nk_flags align)
nk_strtoi
NK_API int nk_strtoi(const char *str, const char **endptr)
nk_property_state::name
nk_hash name
Definition: nuklear.h:5403
nk_configuration_stacks::flags
struct nk_config_stack_flags flags
Definition: nuklear.h:5521
nk_style_toggle::border
float border
Definition: nuklear.h:4875
nk_select_text
NK_API int nk_select_text(struct nk_context *, const char *, int, nk_flags align, int value)
nk_chart_slot::color
struct nk_color color
Definition: nuklear.h:5271
nk_memory_status::size
nk_size size
Definition: nuklear.h:4096
nk_style_scrollbar::cursor_border_color
struct nk_color cursor_border_color
Definition: nuklear.h:4994
nk_style_window::contextual_border_color
struct nk_color contextual_border_color
Definition: nuklear.h:5184
nk_select_image_text
NK_API int nk_select_image_text(struct nk_context *, struct nk_image, const char *, int, nk_flags align, int value)
NK_COMMAND_CUSTOM
@ NK_COMMAND_CUSTOM
Definition: nuklear.h:4394
nk_buffer_marker
Definition: nuklear.h:4113
nk_style_window_header::label_padding
struct nk_vec2 label_padding
Definition: nuklear.h:5172
nk_contextual_item_symbol_text
NK_API int nk_contextual_item_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags alignment)
nk_style_button::draw_begin
void(* draw_begin)(struct nk_command_buffer *, nk_handle userdata)
Definition: nuklear.h:4849
NK_WINDOW_HIDDEN
@ NK_WINDOW_HIDDEN
Definition: nuklear.h:5361
nk_text_undo_state::undo_point
short undo_point
Definition: nuklear.h:4264
nk_plot
NK_API void nk_plot(struct nk_context *, enum nk_chart_type, const float *values, int count, int offset)
nk_text_undo_record::where
int where
Definition: nuklear.h:4255
nk_image::w
unsigned short w
Definition: nuklear.h:466
nk_style_toggle::draw_begin
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4879
nk_style_property::padding
struct nk_vec2 padding
Definition: nuklear.h:5069
nk_input_is_mouse_prev_hovering_rect
NK_API int nk_input_is_mouse_prev_hovering_rect(const struct nk_input *, struct nk_rect)
NK_SHOWN
@ NK_SHOWN
Definition: nuklear.h:475
nk_buffer_init
NK_API void nk_buffer_init(struct nk_buffer *, const struct nk_allocator *, nk_size size)
nk_list_view::begin
int begin
Definition: nuklear.h:3028
nk_key::clicked
unsigned int clicked
Definition: nuklear.h:4618
nk_style_progress::active
struct nk_style_item active
Definition: nuklear.h:4961
nk_begin
NK_API int nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags)
nk_chart::slot
int slot
Definition: nuklear.h:5280
NK_MAX_NUMBER_BUFFER
#define NK_MAX_NUMBER_BUFFER
Definition: nuklear.h:240
NK_MAXIMIZED
@ NK_MAXIMIZED
Definition: nuklear.h:474
nk_configuration_stacks::style_items
struct nk_config_stack_style_item style_items
Definition: nuklear.h:5518
nk_vec2
NK_API struct nk_vec2 nk_vec2(float x, float y)
nk_style::option
struct nk_style_toggle option
Definition: nuklear.h:5224
nk_context::build
int build
Definition: nuklear.h:5599
NK_KEY_TEXT_SELECT_ALL
@ NK_KEY_TEXT_SELECT_ALL
Definition: nuklear.h:761
nk_command_scissor::y
short y
Definition: nuklear.h:4408
nk_layout_row_template_push_dynamic
NK_API void nk_layout_row_template_push_dynamic(struct nk_context *)
nk_label
NK_API void nk_label(struct nk_context *, const char *, nk_flags align)
nk_style_progress::cursor_rounding
float cursor_rounding
Definition: nuklear.h:4974
nk_style_property::label_active
struct nk_color label_active
Definition: nuklear.h:5060
nk_command_polyline::line_thickness
unsigned short line_thickness
Definition: nuklear.h:4523
nk_window::tables
struct nk_table * tables
Definition: nuklear.h:5427
nk_text_edit::clip
struct nk_clipboard clip
Definition: nuklear.h:4282
NK_KEY_TEXT_RESET_MODE
@ NK_KEY_TEXT_RESET_MODE
Definition: nuklear.h:754
NK_KEY_TEXT_REDO
@ NK_KEY_TEXT_REDO
Definition: nuklear.h:760
nk_style::cursors
const struct nk_cursor * cursors[NK_CURSOR_COUNT]
Definition: nuklear.h:5215
nk_str_insert_str_runes
NK_API int nk_str_insert_str_runes(struct nk_str *, int pos, const nk_rune *)
nk_stroke_triangle
NK_API void nk_stroke_triangle(struct nk_command_buffer *, float, float, float, float, float, float, float line_thichness, struct nk_color)
nk_edit_types
nk_edit_types
Definition: nuklear.h:3431
nk_text_edit::mode
unsigned char mode
Definition: nuklear.h:4290
nk_row_layout::filled
float filled
Definition: nuklear.h:5307
NK_COMMAND_POLYGON
@ NK_COMMAND_POLYGON
Definition: nuklear.h:4389
nk_context::input
struct nk_input input
Definition: nuklear.h:5572
nk_panel_row_layout_type
nk_panel_row_layout_type
Definition: nuklear.h:5285
nk_cursor
Definition: nuklear.h:467
nk_table::next
struct nk_table * next
Definition: nuklear.h:5538
nk_recti::x
short x
Definition: nuklear.h:463
nk_style_window_header::close_button
struct nk_style_button close_button
Definition: nuklear.h:5158
nk_window_find
NK_API struct nk_window * nk_window_find(struct nk_context *ctx, const char *name)
NK_EDIT_MULTILINE
@ NK_EDIT_MULTILINE
Definition: nuklear.h:3428
nk_style_item_data
Definition: nuklear.h:4811
nk_command_image::x
short x
Definition: nuklear.h:4530
nk_style_item_hide
NK_API struct nk_style_item nk_style_item_hide(void)
nk_keys
nk_keys
Definition: nuklear.h:736
nk_style_selectable::draw_end
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4915
nk_command_triangle_filled
Definition: nuklear.h:4465
NK_KEY_TEXT_WORD_LEFT
@ NK_KEY_TEXT_WORD_LEFT
Definition: nuklear.h:762
nk_str_append_text_char
NK_API int nk_str_append_text_char(struct nk_str *, const char *, int)
NK_COMMAND_POLYGON_FILLED
@ NK_COMMAND_POLYGON_FILLED
Definition: nuklear.h:4390
nk_style_scrollbar::draw_begin
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:5012
nk_style_combo::normal
struct nk_style_item normal
Definition: nuklear.h:5096
nk_style_selectable::hover_active
struct nk_style_item hover_active
Definition: nuklear.h:4891
nk_command_image::h
unsigned short h
Definition: nuklear.h:4531
nk_allocator::userdata
nk_handle userdata
Definition: nuklear.h:490
nk_configuration_stacks::button_behaviors
struct nk_config_stack_button_behavior button_behaviors
Definition: nuklear.h:5524
nk_strtof
NK_API float nk_strtof(const char *str, const char **endptr)
nk_chart_slot
Definition: nuklear.h:5269
NK_DYNAMIC
@ NK_DYNAMIC
Definition: nuklear.h:480
nk_widget_fitting
NK_API enum nk_widget_layout_states nk_widget_fitting(struct nk_rect *, struct nk_context *, struct nk_vec2)
nk_plugin_filter
int(* nk_plugin_filter)(const struct nk_text_edit *, nk_rune unicode)
Definition: nuklear.h:485
nk_utf_encode
NK_API int nk_utf_encode(nk_rune, char *, int)
nk_cursor::img
struct nk_image img
Definition: nuklear.h:467
nk_style_toggle::touch_padding
struct nk_vec2 touch_padding
Definition: nuklear.h:4873
nk_window::flags
nk_flags flags
Definition: nuklear.h:5413
nk_modify
nk_modify
Definition: nuklear.h:472
nk_allocator
Definition: nuklear.h:489
nk_str_at_char
NK_API char * nk_str_at_char(struct nk_str *, int pos)
nk_window::parent
struct nk_window * parent
Definition: nuklear.h:5433
nk_style_button::hover
struct nk_style_item hover
Definition: nuklear.h:4829
nk_init_custom
NK_API int nk_init_custom(struct nk_context *, struct nk_buffer *cmds, struct nk_buffer *pool, const struct nk_user_font *)
nk_row_layout::type
enum nk_panel_row_layout_type type
Definition: nuklear.h:5298
nk_button_symbol_text
NK_API int nk_button_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags alignment)
nk_style_property::border_color
struct nk_color border_color
Definition: nuklear.h:5055
NK_EDIT_ALWAYS_INSERT_MODE
@ NK_EDIT_ALWAYS_INSERT_MODE
Definition: nuklear.h:3427
NK_SYMBOL_TRIANGLE_UP
@ NK_SYMBOL_TRIANGLE_UP
Definition: nuklear.h:502
nk_pool::pages
struct nk_page * pages
Definition: nuklear.h:5563
nk_user_font::userdata
nk_handle userdata
Definition: nuklear.h:3916
nk_menubar_end
NK_API void nk_menubar_end(struct nk_context *)
nk_combo_callback
NK_API int nk_combo_callback(struct nk_context *, void(*item_getter)(void *, int, const char **), void *userdata, int selected, int count, int item_height, struct nk_vec2 size)
nk_text_edit::single_line
unsigned char single_line
Definition: nuklear.h:4294
nk_style_combo::border_color
struct nk_color border_color
Definition: nuklear.h:5099
NK_SYMBOL_MINUS
@ NK_SYMBOL_MINUS
Definition: nuklear.h:507
nk_command_line::header
struct nk_command header
Definition: nuklear.h:4413
nk_button_symbol_styled
NK_API int nk_button_symbol_styled(struct nk_context *, const struct nk_style_button *, enum nk_symbol_type)
nk_chart_slot::range
float range
Definition: nuklear.h:5273
nk_style_button::text_alignment
nk_flags text_alignment
Definition: nuklear.h:4838
nk_command_rect_multi_color::right
struct nk_color right
Definition: nuklear.h:4453
nk_stroke_curve
NK_API void nk_stroke_curve(struct nk_command_buffer *, float, float, float, float, float, float, float, float, float line_thickness, struct nk_color)
nk_layout_space_bounds
NK_API struct nk_rect nk_layout_space_bounds(struct nk_context *)
nk_style_window::rounding
float rounding
Definition: nuklear.h:5199
nk_subimage_handle
NK_API struct nk_image nk_subimage_handle(nk_handle, unsigned short w, unsigned short h, struct nk_rect sub_region)
nk_window_is_collapsed
NK_API int nk_window_is_collapsed(struct nk_context *ctx, const char *name)
NK_KEY_CTRL
@ NK_KEY_CTRL
Definition: nuklear.h:739
NK_HIDDEN
@ NK_HIDDEN
Definition: nuklear.h:475
nk_popup_begin
NK_API int nk_popup_begin(struct nk_context *, enum nk_popup_type, const char *, nk_flags, struct nk_rect bounds)
nk_group_set_scroll
NK_API void nk_group_set_scroll(struct nk_context *, const char *id, nk_uint x_offset, nk_uint y_offset)
nk_text_align
nk_text_align
Definition: nuklear.h:3073
nk_style_scrollbar::padding
struct nk_vec2 padding
Definition: nuklear.h:5001
nk_color_hsv_f
NK_API void nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color)
nk_window_set_focus
NK_API void nk_window_set_focus(struct nk_context *, const char *name)
nk_popup_get_scroll
NK_API void nk_popup_get_scroll(struct nk_context *, nk_uint *offset_x, nk_uint *offset_y)
nk_command_arc::color
struct nk_color color
Definition: nuklear.h:4494
nk_text
NK_API void nk_text(struct nk_context *, const char *, int, nk_flags)
nk_input::mouse
struct nk_mouse mouse
Definition: nuklear.h:4628
nk_tree_element_pop
NK_API void nk_tree_element_pop(struct nk_context *)
nk_hsv
NK_API struct nk_color nk_hsv(int h, int s, int v)
nk_style_scrollbar::hover
struct nk_style_item hover
Definition: nuklear.h:4986
nk_style_selectable::normal
struct nk_style_item normal
Definition: nuklear.h:4885
nk_style_push_flags
NK_API int nk_style_push_flags(struct nk_context *, nk_flags *, nk_flags)
nk_style_property::hover
struct nk_style_item hover
Definition: nuklear.h:5053
nk_style_property::edit
struct nk_style_edit edit
Definition: nuklear.h:5071
NK_EDIT_EDITOR
@ NK_EDIT_EDITOR
Definition: nuklear.h:3435
nk_style_tab::sym_minimize
enum nk_symbol_type sym_minimize
Definition: nuklear.h:5136
nk_style_combo::border
float border
Definition: nuklear.h:5118
nk_text_edit_type
nk_text_edit_type
Definition: nuklear.h:4270
nk_layout_reset_min_row_height
NK_API void nk_layout_reset_min_row_height(struct nk_context *)
NK_MAX_FLOAT_PRECISION
#define NK_MAX_FLOAT_PRECISION
Definition: nuklear.h:5616
nk_scroll::y
nk_uint y
Definition: nuklear.h:468
NK_POINTER_TYPE
#define NK_POINTER_TYPE
Definition: nuklear.h:394
nk_style_window::padding
struct nk_vec2 padding
Definition: nuklear.h:5204
nk_pool::freelist
struct nk_page_element * freelist
Definition: nuklear.h:5564
nk_hsva_colorfv
NK_API struct nk_colorf nk_hsva_colorfv(float *c)
nk_window_collapse_if
NK_API void nk_window_collapse_if(struct nk_context *, const char *name, enum nk_collapse_states, int cond)
nk_fill_rect_multi_color
NK_API void nk_fill_rect_multi_color(struct nk_command_buffer *, struct nk_rect, struct nk_color left, struct nk_color top, struct nk_color right, struct nk_color bottom)
nk_anti_aliasing
nk_anti_aliasing
Definition: nuklear.h:1143
nk_list_view_end
NK_API void nk_list_view_end(struct nk_list_view *)
nk_free
NK_API void nk_free(struct nk_context *)
nk_style_button::text_active
struct nk_color text_active
Definition: nuklear.h:4837
nk_page_data::tbl
struct nk_table tbl
Definition: nuklear.h:5542
nk_style_window_header::normal
struct nk_style_item normal
Definition: nuklear.h:5153
nk_style_window::scaler
struct nk_style_item scaler
Definition: nuklear.h:5188
nk_ptr_add_const
#define nk_ptr_add_const(t, p, i)
Definition: nuklear.h:5636
nk_textedit_delete_selection
NK_API void nk_textedit_delete_selection(struct nk_text_edit *)
nk_hsv_fv
NK_API struct nk_color nk_hsv_fv(const float *hsv)
nk_style_edit::text_normal
struct nk_color text_normal
Definition: nuklear.h:5031
nk_convert_config::curve_segment_count
unsigned curve_segment_count
Definition: nuklear.h:1161
nk_text_colored
NK_API void nk_text_colored(struct nk_context *, const char *, int, nk_flags, struct nk_color)
nk_command_curve::color
struct nk_color color
Definition: nuklear.h:4426
NK_SYMBOL_TRIANGLE_DOWN
@ NK_SYMBOL_TRIANGLE_DOWN
Definition: nuklear.h:503
NK_TEXT_CENTERED
@ NK_TEXT_CENTERED
Definition: nuklear.h:3083
nk_str_append_text_utf8
NK_API int nk_str_append_text_utf8(struct nk_str *, const char *, int)
nk_command_arc_filled::r
unsigned short r
Definition: nuklear.h:4500
nk_color_f
NK_API void nk_color_f(float *r, float *g, float *b, float *a, struct nk_color)
nk_popup_state::buf
struct nk_popup_buffer buf
Definition: nuklear.h:5374
nk_style_set_cursor
NK_API int nk_style_set_cursor(struct nk_context *, enum nk_style_cursor)
nk_context::pool
struct nk_pool pool
Definition: nuklear.h:5601
nk_command_rect_multi_color::x
short x
Definition: nuklear.h:4448
nk_button_set_behavior
NK_API void nk_button_set_behavior(struct nk_context *, enum nk_button_behavior)
nk_style_selectable::text_alignment
nk_flags text_alignment
Definition: nuklear.h:4904
NK_LIB
#define NK_LIB
Definition: nuklear.h:267
nk_group_get_scroll
NK_API void nk_group_get_scroll(struct nk_context *, const char *id, nk_uint *x_offset, nk_uint *y_offset)
nk_widget_is_mouse_clicked
NK_API int nk_widget_is_mouse_clicked(struct nk_context *, enum nk_buttons)
NK_SATURATE
#define NK_SATURATE(x)
Definition: nuklear.h:5619
NK_WINDOW_CLOSED
@ NK_WINDOW_CLOSED
Definition: nuklear.h:5363
nk_buffer_memory_const
NK_API const void * nk_buffer_memory_const(const struct nk_buffer *)
NK_GLOBAL
#define NK_GLOBAL
Definition: nuklear.h:275
nk_page_data::pan
struct nk_panel pan
Definition: nuklear.h:5543
nk_style_chart::color
struct nk_color color
Definition: nuklear.h:5086
nk_style_tab::tab_minimize_button
struct nk_style_button tab_minimize_button
Definition: nuklear.h:5133
nk_command_curve::header
struct nk_command header
Definition: nuklear.h:4421
nk_menu_state::x
float x
Definition: nuklear.h:5322
NK_CHART_CLICKED
@ NK_CHART_CLICKED
Definition: nuklear.h:477
nk_context::end
struct nk_window * end
Definition: nuklear.h:5603
nk_style_edit
Definition: nuklear.h:5016
NK_PANEL_MENU
@ NK_PANEL_MENU
Definition: nuklear.h:5260
NK_EDIT_CLIPBOARD
@ NK_EDIT_CLIPBOARD
Definition: nuklear.h:3424
NK_BUTTON_DEFAULT
@ NK_BUTTON_DEFAULT
Definition: nuklear.h:471
nk_style_slider::normal
struct nk_style_item normal
Definition: nuklear.h:4920
nk_page_data::win
struct nk_window win
Definition: nuklear.h:5544
NK_ABS
#define NK_ABS(a)
Definition: nuklear.h:5621
nk_command_circle_filled
Definition: nuklear.h:4481
nk_command_circle::w
unsigned short w
Definition: nuklear.h:4477
NK_WIDGET_STATE_LEFT
@ NK_WIDGET_STATE_LEFT
Definition: nuklear.h:3053
nk_style_property::border
float border
Definition: nuklear.h:5067
nk_menu_state::offset
struct nk_scroll offset
Definition: nuklear.h:5323
NK_KEY_TEXT_LINE_START
@ NK_KEY_TEXT_LINE_START
Definition: nuklear.h:755
nk__next
NK_API const struct nk_command * nk__next(struct nk_context *, const struct nk_command *)
nk_color_picker
NK_API struct nk_colorf nk_color_picker(struct nk_context *, struct nk_colorf, enum nk_color_format)
nk_layout_set_min_row_height
NK_API void nk_layout_set_min_row_height(struct nk_context *, float height)
nk_convert_config::line_AA
enum nk_anti_aliasing line_AA
Definition: nuklear.h:1157
nk_tree_element_image_push_hashed
NK_API int nk_tree_element_image_push_hashed(struct nk_context *, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states initial_state, int *selected, const char *hash, int len, int seed)
NK_INT8
#define NK_INT8
Definition: nuklear.h:342
nk_page_data
Definition: nuklear.h:5541
nk_list_view::count
int count
Definition: nuklear.h:3028
nk_size
NK_SIZE_TYPE nk_size
Definition: nuklear.h:406
nk_command_custom::callback
nk_command_custom_callback callback
Definition: nuklear.h:4543
nk_image
NK_API void nk_image(struct nk_context *, struct nk_image)
nk_image
Definition: nuklear.h:466
NK_WIDGET_STATE_MODIFIED
@ NK_WIDGET_STATE_MODIFIED
Definition: nuklear.h:3048
nk_contextual_end
NK_API void nk_contextual_end(struct nk_context *)
nk_input_glyph
NK_API void nk_input_glyph(struct nk_context *, const nk_glyph)
nk_style_slider::spacing
struct nk_vec2 spacing
Definition: nuklear.h:4941
nk_text_edit
Definition: nuklear.h:4281
nk_window::next
struct nk_window * next
Definition: nuklear.h:5431
nk_key
Definition: nuklear.h:4616
nk_style_slider::bar_height
float bar_height
Definition: nuklear.h:4939
nk_command_rect_multi_color::left
struct nk_color left
Definition: nuklear.h:4450
nk_color::g
nk_byte g
Definition: nuklear.h:458
nk_command_custom::header
struct nk_command header
Definition: nuklear.h:4539
nk_combo_item_symbol_label
NK_API int nk_combo_item_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags alignment)
nk_push_scissor
NK_API void nk_push_scissor(struct nk_command_buffer *, struct nk_rect)
nk_style_edit::text_hover
struct nk_color text_hover
Definition: nuklear.h:5032
nk_style_button::text_normal
struct nk_color text_normal
Definition: nuklear.h:4835
NK_KEY_LEFT
@ NK_KEY_LEFT
Definition: nuklear.h:749
NK_CLAMP
#define NK_CLAMP(i, v, x)
Definition: nuklear.h:304
NK_SIZE_TYPE
#define NK_SIZE_TYPE
Definition: nuklear.h:379
nk_progress
NK_API int nk_progress(struct nk_context *, nk_size *cur, nk_size max, int modifyable)
nk_style_item_data::color
struct nk_color color
Definition: nuklear.h:4813
NK_FLAG
#define NK_FLAG(x)
Definition: nuklear.h:277
nk_style_edit::padding
struct nk_vec2 padding
Definition: nuklear.h:5046
NK_WIDGET_INVALID
@ NK_WIDGET_INVALID
Definition: nuklear.h:3043
nk_style_tab::background
struct nk_style_item background
Definition: nuklear.h:5127
nk_configuration_stacks::colors
struct nk_config_stack_color colors
Definition: nuklear.h:5522
nk_button_image_text_styled
NK_API int nk_button_image_text_styled(struct nk_context *, const struct nk_style_button *, struct nk_image img, const char *, int, nk_flags alignment)
NK_KEY_TEXT_END
@ NK_KEY_TEXT_END
Definition: nuklear.h:758
nk_style_scrollbar
Definition: nuklear.h:4983
nk_plugin_paste
void(* nk_plugin_paste)(nk_handle, struct nk_text_edit *)
Definition: nuklear.h:486
nk_stricmp
NK_API int nk_stricmp(const char *s1, const char *s2)
nk_utf_at
NK_API const char * nk_utf_at(const char *buffer, int length, int index, nk_rune *unicode, int *len)
nk_vec2i::y
short y
Definition: nuklear.h:461
nk_command_text::string
char string[1]
Definition: nuklear.h:4555
nk_str_at_rune
NK_API char * nk_str_at_rune(struct nk_str *, int pos, nk_rune *unicode, int *len)
nk_vec2_sub
#define nk_vec2_sub(a, b)
Definition: nuklear.h:5630
nk_style_toggle::text_active
struct nk_color text_active
Definition: nuklear.h:4867
nk_table::seq
unsigned int seq
Definition: nuklear.h:5534
nk_style_window::border
float border
Definition: nuklear.h:5190
NK_ALIGN_PTR
#define NK_ALIGN_PTR(x, mask)
Definition: nuklear.h:5657
nk_layout_space_end
NK_API void nk_layout_space_end(struct nk_context *)
nk_input_scroll
NK_API void nk_input_scroll(struct nk_context *, struct nk_vec2 val)
NK_UP
@ NK_UP
Definition: nuklear.h:470
nk_hsva_bv
NK_API struct nk_color nk_hsva_bv(const nk_byte *hsva)
NK_WIDGET_STATE_HOVERED
@ NK_WIDGET_STATE_HOVERED
Definition: nuklear.h:3054
nk_draw_null_texture::uv
struct nk_vec2 uv
Definition: nuklear.h:1153
nk_menu_state::y
float y
Definition: nuklear.h:5322
nk_input_is_key_down
NK_API int nk_input_is_key_down(const struct nk_input *, enum nk_keys)
nk_label_wrap
NK_API void nk_label_wrap(struct nk_context *, const char *)
nk_vec2::y
float y
Definition: nuklear.h:460
nk_layout_space_rect_to_screen
NK_API struct nk_rect nk_layout_space_rect_to_screen(struct nk_context *, struct nk_rect)
nk_style_progress::border
float border
Definition: nuklear.h:4972
NK_CHART_LINES
@ NK_CHART_LINES
Definition: nuklear.h:476
nk_popup_state::con_old
unsigned con_old
Definition: nuklear.h:5378
nk_popup_buffer::parent
nk_size parent
Definition: nuklear.h:5315
NK_PI
#define NK_PI
Definition: nuklear.h:5614
nk_command_rect_multi_color
Definition: nuklear.h:4446
nk_color_hsva_bv
NK_API void nk_color_hsva_bv(nk_byte *hsva_out, struct nk_color)
nk_style_window_header
Definition: nuklear.h:5151
nk_text_edit::filter
nk_plugin_filter filter
Definition: nuklear.h:4284
nk_style_scrollbar::cursor_active
struct nk_style_item cursor_active
Definition: nuklear.h:4993
NK_COMMAND_RECT_MULTI_COLOR
@ NK_COMMAND_RECT_MULTI_COLOR
Definition: nuklear.h:4382
nk_window::seq
unsigned int seq
Definition: nuklear.h:5410
nk_tree_state_pop
NK_API void nk_tree_state_pop(struct nk_context *)
nk_strlen
NK_API int nk_strlen(const char *str)
nk_text_undo_record
Definition: nuklear.h:4254
nk_textedit_text
NK_API void nk_textedit_text(struct nk_text_edit *, const char *, int total_len)
nk_command_scissor::w
unsigned short w
Definition: nuklear.h:4409
nk_popup_type
nk_popup_type
Definition: nuklear.h:479
nk_contextual_close
NK_API void nk_contextual_close(struct nk_context *)
NK_KEY_DEL
@ NK_KEY_DEL
Definition: nuklear.h:740
nk_style_property::draw_begin
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:5077
nk_color::r
nk_byte r
Definition: nuklear.h:458
nk_style_property::inc_button
struct nk_style_button inc_button
Definition: nuklear.h:5072
nk_strmatch_fuzzy_text
NK_API int nk_strmatch_fuzzy_text(const char *txt, int txt_len, const char *pattern, int *out_score)
nk_style_tab::padding
struct nk_vec2 padding
Definition: nuklear.h:5143
nk_command_arc::cx
short cx
Definition: nuklear.h:4490
nk_combo_begin_label
NK_API int nk_combo_begin_label(struct nk_context *, const char *selected, struct nk_vec2 size)
NK_COMMAND_TRIANGLE
@ NK_COMMAND_TRIANGLE
Definition: nuklear.h:4387
nk_select_symbol_text
NK_API int nk_select_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags align, int value)
nk_command_polygon::line_thickness
unsigned short line_thickness
Definition: nuklear.h:4508
nk_chart
Definition: nuklear.h:5279
nk_buffer::memory
struct nk_memory memory
Definition: nuklear.h:4126
nk_rgb
NK_API struct nk_color nk_rgb(int r, int g, int b)
nk_style_edit::normal
struct nk_style_item normal
Definition: nuklear.h:5018
nk_layout_space_push
NK_API void nk_layout_space_push(struct nk_context *, struct nk_rect bounds)
nk_table::values
nk_uint values[NK_VALUE_PAGE_CAPACITY]
Definition: nuklear.h:5537
nk_color::a
nk_byte a
Definition: nuklear.h:458
nk_char
NK_INT8 nk_char
Definition: nuklear.h:399
nk_style_button::image_padding
struct nk_vec2 image_padding
Definition: nuklear.h:4844
NK_LAYOUT_STATIC_FIXED
@ NK_LAYOUT_STATIC_FIXED
Definition: nuklear.h:5290
nk_style_button::touch_padding
struct nk_vec2 touch_padding
Definition: nuklear.h:4845
nk_popup_buffer::begin
nk_size begin
Definition: nuklear.h:5314
nk_panel::type
enum nk_panel_type type
Definition: nuklear.h:5327
nk_text_edit::cursor
int cursor
Definition: nuklear.h:4287
nk_color_u32
NK_API nk_uint nk_color_u32(struct nk_color)
nk_str_insert_text_char
NK_API int nk_str_insert_text_char(struct nk_str *, int pos, const char *, int)
nk_fill_arc
NK_API void nk_fill_arc(struct nk_command_buffer *, float cx, float cy, float radius, float a_min, float a_max, struct nk_color)
NK_UTF_SIZE
#define NK_UTF_SIZE
Definition: nuklear.h:235
nk_filter_ascii
NK_API int nk_filter_ascii(const struct nk_text_edit *, nk_rune unicode)
nk_combo
NK_API int nk_combo(struct nk_context *, const char **items, int count, int selected, int item_height, struct nk_vec2 size)
NK_INBOX
#define NK_INBOX(px, py, x, y, w, h)
Definition: nuklear.h:5623
nk_rgba
NK_API struct nk_color nk_rgba(int r, int g, int b, int a)
nk_style_progress::draw_end
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4980
nk_style_text
Definition: nuklear.h:4821
nk_command_line::line_thickness
unsigned short line_thickness
Definition: nuklear.h:4414
nk_rect::w
float w
Definition: nuklear.h:462
nk_style_load_cursor
NK_API void nk_style_load_cursor(struct nk_context *, enum nk_style_cursor, const struct nk_cursor *)
nk_style_slider::draw_end
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4954
nk_style_chart::rounding
float rounding
Definition: nuklear.h:5090
nk_flags
nk_uint nk_flags
Definition: nuklear.h:410
nk_popup_close
NK_API void nk_popup_close(struct nk_context *)
nk_text_edit::string
struct nk_str string
Definition: nuklear.h:4283
NK_INT16
#define NK_INT16
Definition: nuklear.h:348
nk_property_state::buffer
char buffer[NK_MAX_NUMBER_BUFFER]
Definition: nuklear.h:5398
nk_style_property::sym_right
enum nk_symbol_type sym_right
Definition: nuklear.h:5064
nk_mouse_button::clicked
unsigned int clicked
Definition: nuklear.h:4602
NK_SYMBOL_RECT_SOLID
@ NK_SYMBOL_RECT_SOLID
Definition: nuklear.h:500
nk_style_progress::draw_begin
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4979
nk_str_append_text_runes
NK_API int nk_str_append_text_runes(struct nk_str *, const nk_rune *, int)
nk_color_fv
NK_API void nk_color_fv(float *rgba_out, struct nk_color)
nk_style::font
const struct nk_user_font * font
Definition: nuklear.h:5214
nk_stricmpn
NK_API int nk_stricmpn(const char *s1, const char *s2, int n)
nk_style_progress::rounding
float rounding
Definition: nuklear.h:4971
nk_button_label_styled
NK_API int nk_button_label_styled(struct nk_context *, const struct nk_style_button *, const char *title)
nk_edit_state
Definition: nuklear.h:5383
nk_str_clear
NK_API void nk_str_clear(struct nk_str *)
nk_style_item
Definition: nuklear.h:4816
nk_buffer_push
NK_API void nk_buffer_push(struct nk_buffer *, enum nk_buffer_allocation_type type, const void *memory, nk_size size, nk_size align)
NK_WINDOW_BACKGROUND
@ NK_WINDOW_BACKGROUND
Definition: nuklear.h:1460
nk_group_scrolled_end
NK_API void nk_group_scrolled_end(struct nk_context *)
nk_command_rect_multi_color::bottom
struct nk_color bottom
Definition: nuklear.h:4452
nk_list_view::scroll_pointer
nk_uint * scroll_pointer
Definition: nuklear.h:3032
nk_textedit_init
NK_API void nk_textedit_init(struct nk_text_edit *, struct nk_allocator *, nk_size size)
nk_context::active
struct nk_window * active
Definition: nuklear.h:5604
nk_rect
NK_API struct nk_rect nk_rect(float x, float y, float w, float h)
nk_textedit_cut
NK_API int nk_textedit_cut(struct nk_text_edit *)
nk_style_window_header::label_normal
struct nk_color label_normal
Definition: nuklear.h:5165
nk_color_hsv_bv
NK_API void nk_color_hsv_bv(nk_byte *hsv_out, struct nk_color)
NK_CURSOR_COUNT
@ NK_CURSOR_COUNT
Definition: nuklear.h:3601
NK_CURSOR_RESIZE_TOP_RIGHT_DOWN_LEFT
@ NK_CURSOR_RESIZE_TOP_RIGHT_DOWN_LEFT
Definition: nuklear.h:3600
NK_TEXTEDIT_UNDOCHARCOUNT
#define NK_TEXTEDIT_UNDOCHARCOUNT
Definition: nuklear.h:4244
nk_property_int
NK_API void nk_property_int(struct nk_context *, const char *name, int min, int *val, int max, int step, float inc_per_pixel)
NK_SYMBOL_TRIANGLE_LEFT
@ NK_SYMBOL_TRIANGLE_LEFT
Definition: nuklear.h:504
nk_page_element::data
union nk_page_data data
Definition: nuklear.h:5548
nk_text_wrap
NK_API void nk_text_wrap(struct nk_context *, const char *, int)
nk_stroke_line
NK_API void nk_stroke_line(struct nk_command_buffer *b, float x0, float y0, float x1, float y1, float line_thickness, struct nk_color)
nk_true
@ nk_true
Definition: nuklear.h:457
nk_style_scrollbar::normal
struct nk_style_item normal
Definition: nuklear.h:4985
nk_stroke_arc
NK_API void nk_stroke_arc(struct nk_command_buffer *, float cx, float cy, float radius, float a_min, float a_max, float line_thickness, struct nk_color)
nk_style_window_header::active
struct nk_style_item active
Definition: nuklear.h:5155
nk_input_is_mouse_released
NK_API int nk_input_is_mouse_released(const struct nk_input *, enum nk_buttons)
NK_CHART_MAX
@ NK_CHART_MAX
Definition: nuklear.h:476
nk_row_layout::columns
int columns
Definition: nuklear.h:5302
nk_push_custom
NK_API void nk_push_custom(struct nk_command_buffer *, struct nk_rect, nk_command_custom_callback, nk_handle usr)
nk_popup_state::active_con
unsigned active_con
Definition: nuklear.h:5379
nk_layout_row_template_begin
NK_API void nk_layout_row_template_begin(struct nk_context *, float row_height)
nk_color_cf
NK_API struct nk_colorf nk_color_cf(struct nk_color)
nk_buffer_mark
NK_API void nk_buffer_mark(struct nk_buffer *, enum nk_buffer_allocation_type type)
nk_style_window::min_row_height_padding
float min_row_height_padding
Definition: nuklear.h:5197
nk_command_rect_filled::h
unsigned short h
Definition: nuklear.h:4442
NK_COLOR_PROPERTY
@ NK_COLOR_PROPERTY
Definition: nuklear.h:3579
nk_style_window_header::minimize_button
struct nk_style_button minimize_button
Definition: nuklear.h:5159
nk_style_item::type
enum nk_style_item_type type
Definition: nuklear.h:4817
nk_rune
nk_uint nk_rune
Definition: nuklear.h:411
nk_button_image_styled
NK_API int nk_button_image_styled(struct nk_context *, const struct nk_style_button *, struct nk_image img)
nk_input_is_mouse_click_in_rect
NK_API int nk_input_is_mouse_click_in_rect(const struct nk_input *, enum nk_buttons, struct nk_rect)
nk_draw_null_texture
Definition: nuklear.h:1151
nk_uint
NK_UINT32 nk_uint
Definition: nuklear.h:405
nk_style_toggle::draw_end
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4880
NK_VECTOR_STACK_SIZE
#define NK_VECTOR_STACK_SIZE
Definition: nuklear.h:5478
NK_EDIT_GOTO_END_ON_ACTIVATE
@ NK_EDIT_GOTO_END_ON_ACTIVATE
Definition: nuklear.h:3429
nk_color
Definition: nuklear.h:458
nk_style_window::border_color
struct nk_color border_color
Definition: nuklear.h:5181
nk_mouse::grab
unsigned char grab
Definition: nuklear.h:4611
nk_style_scrollbar::rounding
float rounding
Definition: nuklear.h:4998
nk_button_behavior
nk_button_behavior
Definition: nuklear.h:471
nk_draw_text
NK_API void nk_draw_text(struct nk_command_buffer *, struct nk_rect, const char *text, int len, const struct nk_user_font *, struct nk_color, struct nk_color)
NK_CURSOR_TEXT
@ NK_CURSOR_TEXT
Definition: nuklear.h:3595
nk_tree_type
nk_tree_type
Definition: nuklear.h:481
nk_command::next
nk_size next
Definition: nuklear.h:4400
nk_image_ptr
NK_API struct nk_image nk_image_ptr(void *)
NK_LAYOUT_STATIC_ROW
@ NK_LAYOUT_STATIC_ROW
Definition: nuklear.h:5291
nk_style_push_font
NK_API int nk_style_push_font(struct nk_context *, const struct nk_user_font *)
nk_widget_layout_states
nk_widget_layout_states
Definition: nuklear.h:3042
NK_KEY_TEXT_WORD_RIGHT
@ NK_KEY_TEXT_WORD_RIGHT
Definition: nuklear.h:763
NK_CURSOR_MOVE
@ NK_CURSOR_MOVE
Definition: nuklear.h:3596
nk_command_custom::w
unsigned short w
Definition: nuklear.h:4541
NK_EDIT_DEFAULT
@ NK_EDIT_DEFAULT
Definition: nuklear.h:3417
nk_style_selectable::rounding
float rounding
Definition: nuklear.h:4907
NK_WINDOW_PRIVATE
@ NK_WINDOW_PRIVATE
Definition: nuklear.h:5354
nk_combo_begin_text
NK_API int nk_combo_begin_text(struct nk_context *, const char *selected, int, struct nk_vec2 size)
NK_KEY_TEXT_START
@ NK_KEY_TEXT_START
Definition: nuklear.h:757
nk_command_line::color
struct nk_color color
Definition: nuklear.h:4417
nk_command_rect_multi_color::y
short y
Definition: nuklear.h:4448
NK_LEFT
@ NK_LEFT
Definition: nuklear.h:470
NK_EDIT_ACTIVATED
@ NK_EDIT_ACTIVATED
Definition: nuklear.h:3440
nk_chart_add_slot_colored
NK_API void nk_chart_add_slot_colored(struct nk_context *ctx, const enum nk_chart_type, struct nk_color, struct nk_color active, int count, float min_value, float max_value)
nk_layout_row_dynamic
NK_API void nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols)
nk_style_window::menu_padding
struct nk_vec2 menu_padding
Definition: nuklear.h:5209
nk_layout_space_to_screen
NK_API struct nk_vec2 nk_layout_space_to_screen(struct nk_context *, struct nk_vec2)
nk_contextual_item_symbol_label
NK_API int nk_contextual_item_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags alignment)
nk_style_progress::hover
struct nk_style_item hover
Definition: nuklear.h:4960
nk_table::prev
struct nk_table * prev
Definition: nuklear.h:5538
nk_buffer_marker::active
int active
Definition: nuklear.h:4114
nk_command_text::y
short y
Definition: nuklear.h:4551
nk_command_custom_callback
void(* nk_command_custom_callback)(void *canvas, short x, short y, unsigned short w, unsigned short h, nk_handle callback_data)
Definition: nuklear.h:4536
NK_SYMBOL_X
@ NK_SYMBOL_X
Definition: nuklear.h:496
nk_popup_end
NK_API void nk_popup_end(struct nk_context *)
nk_style_chart::selected_color
struct nk_color selected_color
Definition: nuklear.h:5085
nk_buffer_reset
NK_API void nk_buffer_reset(struct nk_buffer *, enum nk_buffer_allocation_type type)
nk_style_slider::bar_hover
struct nk_color bar_hover
Definition: nuklear.h:4927
nk_mouse_button::down
int down
Definition: nuklear.h:4601
nk_page_element::prev
struct nk_page_element * prev
Definition: nuklear.h:5550
nk_text_undo_state::undo_char
nk_rune undo_char[NK_TEXTEDIT_UNDOCHARCOUNT]
Definition: nuklear.h:4263
nk_filter_binary
NK_API int nk_filter_binary(const struct nk_text_edit *, nk_rune unicode)
nk_color_pick
NK_API int nk_color_pick(struct nk_context *, struct nk_colorf *, enum nk_color_format)
nk_command_polyline::color
struct nk_color color
Definition: nuklear.h:4522
nk_style_pop_float
NK_API int nk_style_pop_float(struct nk_context *)
nk_command_circle::h
unsigned short h
Definition: nuklear.h:4477
nk_window_close
NK_API void nk_window_close(struct nk_context *ctx, const char *name)
NK_BUFFER_DYNAMIC
@ NK_BUFFER_DYNAMIC
Definition: nuklear.h:4104
nk_table::size
unsigned int size
Definition: nuklear.h:5535
nk_style_button::text_background
struct nk_color text_background
Definition: nuklear.h:4834
nk_style_combo::sym_hover
enum nk_symbol_type sym_hover
Definition: nuklear.h:5114
nk_tree_push_hashed
NK_API int nk_tree_push_hashed(struct nk_context *, enum nk_tree_type, const char *title, enum nk_collapse_states initial_state, const char *hash, int len, int seed)
nk_style_tab
Definition: nuklear.h:5125
nk_configuration_stacks::fonts
struct nk_config_stack_user_font fonts
Definition: nuklear.h:5523
nk_stroke_polyline
NK_API void nk_stroke_polyline(struct nk_command_buffer *, float *points, int point_count, float line_thickness, struct nk_color col)
nk_command_line::end
struct nk_vec2i end
Definition: nuklear.h:4416
nk_command_curve::line_thickness
unsigned short line_thickness
Definition: nuklear.h:4422
nk_clipboard::paste
nk_plugin_paste paste
Definition: nuklear.h:4250
NK_COLOR_SCROLLBAR
@ NK_COLOR_SCROLLBAR
Definition: nuklear.h:3586
nk_page::next
struct nk_page * next
Definition: nuklear.h:5555
nk_pool::page_count
unsigned int page_count
Definition: nuklear.h:5562
nk_colorf::b
float b
Definition: nuklear.h:459
NK_COLOR_COMBO
@ NK_COLOR_COMBO
Definition: nuklear.h:3582
nk_command_rect_filled::color
struct nk_color color
Definition: nuklear.h:4443
nk_buffer_memory
NK_API void * nk_buffer_memory(struct nk_buffer *)
nk_style_slider::border
float border
Definition: nuklear.h:4937
nk_style_scrollbar::active
struct nk_style_item active
Definition: nuklear.h:4987
nk_convert_config
Definition: nuklear.h:1155
nk_style_window::background
struct nk_color background
Definition: nuklear.h:5179
nk_command_custom::x
short x
Definition: nuklear.h:4540
nk_text_edit::undo
struct nk_text_undo_state undo
Definition: nuklear.h:4298
nk_init_fixed
NK_API int nk_init_fixed(struct nk_context *, void *memory, nk_size size, const struct nk_user_font *)
NK_FLOAT_STACK_SIZE
#define NK_FLOAT_STACK_SIZE
Definition: nuklear.h:5474
nk_edit_state::prev
int prev
Definition: nuklear.h:5387
nk_rect::y
float y
Definition: nuklear.h:462
nk_style_slider::cursor_normal
struct nk_style_item cursor_normal
Definition: nuklear.h:4932
nk_style_toggle::text_hover
struct nk_color text_hover
Definition: nuklear.h:4866
nk_chart_slot::last
struct nk_vec2 last
Definition: nuklear.h:5275
nk_color_hsva_i
NK_API void nk_color_hsva_i(int *h, int *s, int *v, int *a, struct nk_color)
nk_uchar
NK_UINT8 nk_uchar
Definition: nuklear.h:400
nk_style_combo::sym_active
enum nk_symbol_type sym_active
Definition: nuklear.h:5115
nk_chart_add_slot
NK_API void nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type, int count, float min_value, float max_value)
nk_textedit_init_fixed
NK_API void nk_textedit_init_fixed(struct nk_text_edit *, void *memory, nk_size size)
NK_EDIT_COMMITED
@ NK_EDIT_COMMITED
Definition: nuklear.h:3442
NK_PANEL_CONTEXTUAL
@ NK_PANEL_CONTEXTUAL
Definition: nuklear.h:5258
nk_window_is_hovered
NK_API int nk_window_is_hovered(struct nk_context *)
nk_menu_item_image_label
NK_API int nk_menu_item_image_label(struct nk_context *, struct nk_image, const char *, nk_flags alignment)
nk_style_scrollbar::rounding_cursor
float rounding_cursor
Definition: nuklear.h:5000
nk_page
Definition: nuklear.h:5553
nk_init
NK_API int nk_init(struct nk_context *, struct nk_allocator *, const struct nk_user_font *)
nk_select_symbol_label
NK_API int nk_select_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags align, int value)
nk_command_rect::line_thickness
unsigned short line_thickness
Definition: nuklear.h:4432
nk_style_selectable::userdata
nk_handle userdata
Definition: nuklear.h:4913
NK_COLOR_BORDER
@ NK_COLOR_BORDER
Definition: nuklear.h:3566
NK_KEY_COPY
@ NK_KEY_COPY
Definition: nuklear.h:744
nk_style_combo
Definition: nuklear.h:5094
nk_style_window::combo_border_color
struct nk_color combo_border_color
Definition: nuklear.h:5183
nk_mouse_button::clicked_pos
struct nk_vec2 clicked_pos
Definition: nuklear.h:4603
nk_command_curve::begin
struct nk_vec2i begin
Definition: nuklear.h:4423
NK_COLOR_EDIT_CURSOR
@ NK_COLOR_EDIT_CURSOR
Definition: nuklear.h:3581
nk_input_has_mouse_click_in_rect
NK_API int nk_input_has_mouse_click_in_rect(const struct nk_input *, enum nk_buttons, struct nk_rect)
nk_combo_separator
NK_API int nk_combo_separator(struct nk_context *, const char *items_separated_by_separator, int separator, int selected, int count, int item_height, struct nk_vec2 size)
nk_text_wrap_colored
NK_API void nk_text_wrap_colored(struct nk_context *, const char *, int, struct nk_color)
nk_pool::type
enum nk_allocation_type type
Definition: nuklear.h:5561
nk_window_set_scroll
NK_API void nk_window_set_scroll(struct nk_context *, nk_uint offset_x, nk_uint offset_y)
nk_style_selectable::normal_active
struct nk_style_item normal_active
Definition: nuklear.h:4890
nk_key::down
int down
Definition: nuklear.h:4617
NK_SCROLLBAR_HIDING_TIMEOUT
#define NK_SCROLLBAR_HIDING_TIMEOUT
Definition: nuklear.h:243
nk_str_len_char
NK_API int nk_str_len_char(struct nk_str *)
nk_buffer_init_fixed
NK_API void nk_buffer_init_fixed(struct nk_buffer *, void *memory, nk_size size)
NK_SYMBOL_NONE
@ NK_SYMBOL_NONE
Definition: nuklear.h:495
nk_style_edit::rounding
float rounding
Definition: nuklear.h:5043
NK_COMMAND_ARC
@ NK_COMMAND_ARC
Definition: nuklear.h:4385
nk_window_get_position
NK_API struct nk_vec2 nk_window_get_position(const struct nk_context *ctx)
nk_command_buffer::last
nk_size last
Definition: nuklear.h:4568
nk_command_arc::header
struct nk_command header
Definition: nuklear.h:4489
NK_PANEL_NONE
@ NK_PANEL_NONE
Definition: nuklear.h:5254
nk_color_hex_rgba
NK_API void nk_color_hex_rgba(char *output, struct nk_color)
NK_BUFFER_MAX
@ NK_BUFFER_MAX
Definition: nuklear.h:4110
nk_layout_row_begin
NK_API void nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols)
nk_style_window_header::close_symbol
enum nk_symbol_type close_symbol
Definition: nuklear.h:5160
nk_foreach
#define nk_foreach(c, ctx)
Definition: nuklear.h:1211
nk_command_buffer::begin
nk_size begin
Definition: nuklear.h:4568
nk_label_colored_wrap
NK_API void nk_label_colored_wrap(struct nk_context *, const char *, struct nk_color)
NK_PANEL_TOOLTIP
@ NK_PANEL_TOOLTIP
Definition: nuklear.h:5261
nk_style_toggle::border_color
struct nk_color border_color
Definition: nuklear.h:4858
nk_window::prev
struct nk_window * prev
Definition: nuklear.h:5432
nk_style::contextual_button
struct nk_style_button contextual_button
Definition: nuklear.h:5222
nk_vec2
Definition: nuklear.h:460
nk_text_undo_state
Definition: nuklear.h:4261
nk_style_selectable::touch_padding
struct nk_vec2 touch_padding
Definition: nuklear.h:4909
nk_user_font::width
nk_text_width_f width
Definition: nuklear.h:3920
NK_COLOR_COUNT
@ NK_COLOR_COUNT
Definition: nuklear.h:3591
nk_window::table_count
unsigned int table_count
Definition: nuklear.h:5428
nk_style_combo::button_padding
struct nk_vec2 button_padding
Definition: nuklear.h:5121
nk_recta
NK_API struct nk_rect nk_recta(struct nk_vec2 pos, struct nk_vec2 size)
nk_style_get_color_by_name
NK_API const char * nk_style_get_color_by_name(enum nk_style_colors)
nk_checkbox_flags_text
NK_API int nk_checkbox_flags_text(struct nk_context *, const char *, int, unsigned int *flags, unsigned int value)
nk_plugin_free
void(* nk_plugin_free)(nk_handle, void *old)
Definition: nuklear.h:484
nk_collapse_states
nk_collapse_states
Definition: nuklear.h:474
nk_widget_width
NK_API float nk_widget_width(struct nk_context *)
nk_style_combo::active
struct nk_style_item active
Definition: nuklear.h:5098
NK_POPUP_DYNAMIC
@ NK_POPUP_DYNAMIC
Definition: nuklear.h:479
nk_style_edit::scrollbar_size
struct nk_vec2 scrollbar_size
Definition: nuklear.h:5045
NK_CONVERT_SUCCESS
@ NK_CONVERT_SUCCESS
Definition: nuklear.h:1145
nk_style_item_type
nk_style_item_type
Definition: nuklear.h:4806
nk_rgba_f
NK_API struct nk_color nk_rgba_f(float r, float g, float b, float a)
nk_style_property
Definition: nuklear.h:5050
nk_layout_row_static
NK_API void nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols)
nk_command_image::w
unsigned short w
Definition: nuklear.h:4531
nk_hsva
NK_API struct nk_color nk_hsva(int h, int s, int v, int a)
NK_TEXT_EDIT_MODE_REPLACE
@ NK_TEXT_EDIT_MODE_REPLACE
Definition: nuklear.h:4278
nk_mouse::delta
struct nk_vec2 delta
Definition: nuklear.h:4609
nk_command_triangle_filled::b
struct nk_vec2i b
Definition: nuklear.h:4468
nk_clipboard::userdata
nk_handle userdata
Definition: nuklear.h:4249
nk_context::seq
unsigned int seq
Definition: nuklear.h:5608
nk_window::buffer
struct nk_command_buffer buffer
Definition: nuklear.h:5417
NK_KEY_TEXT_UNDO
@ NK_KEY_TEXT_UNDO
Definition: nuklear.h:759
NK_COLOR_TOGGLE
@ NK_COLOR_TOGGLE
Definition: nuklear.h:3570
nk_memory_status::memory
void * memory
Definition: nuklear.h:4094
nk_mouse::scroll_delta
struct nk_vec2 scroll_delta
Definition: nuklear.h:4610
nk_popup_buffer::end
nk_size end
Definition: nuklear.h:5317
nk_popup_state::con_count
unsigned con_count
Definition: nuklear.h:5378
nk_window_is_hidden
NK_API int nk_window_is_hidden(struct nk_context *, const char *)
nk_style_button::rounding
float rounding
Definition: nuklear.h:4842
nk_style_scrollbar::show_buttons
int show_buttons
Definition: nuklear.h:5004
nk_panel::buffer
struct nk_command_buffer * buffer
Definition: nuklear.h:5341
nk_style_progress::normal
struct nk_style_item normal
Definition: nuklear.h:4959
NK_COLOR_SLIDER_CURSOR_ACTIVE
@ NK_COLOR_SLIDER_CURSOR_ACTIVE
Definition: nuklear.h:3578
NK_STATIC_ASSERT
#define NK_STATIC_ASSERT(exp)
Definition: nuklear.h:291
nk_draw_null_texture::texture
nk_handle texture
Definition: nuklear.h:1152
NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS
#define NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS
Definition: nuklear.h:5247
NK_COLOR_TAB_HEADER
@ NK_COLOR_TAB_HEADER
Definition: nuklear.h:3590
nk_style_selectable::text_normal
struct nk_color text_normal
Definition: nuklear.h:4895
nk_subimage_ptr
NK_API struct nk_image nk_subimage_ptr(void *, unsigned short w, unsigned short h, struct nk_rect sub_region)
nk_command::type
enum nk_command_type type
Definition: nuklear.h:4399
nk_context::freelist
struct nk_page_element * freelist
Definition: nuklear.h:5606
nk_style_show_cursor
NK_API void nk_style_show_cursor(struct nk_context *)
nk_convert_config::circle_segment_count
unsigned circle_segment_count
Definition: nuklear.h:1159
NK_COLOR_TOGGLE_HOVER
@ NK_COLOR_TOGGLE_HOVER
Definition: nuklear.h:3571
nk_style_edit::cursor_text_normal
struct nk_color cursor_text_normal
Definition: nuklear.h:5027
NK_WINDOW_MAX_NAME
#define NK_WINDOW_MAX_NAME
Definition: nuklear.h:5349
nk_item_is_any_active
NK_API int nk_item_is_any_active(struct nk_context *)
NK_WIDGET_STATE_ACTIVE
@ NK_WIDGET_STATE_ACTIVE
Definition: nuklear.h:3055
nk_combo_begin_symbol
NK_API int nk_combo_begin_symbol(struct nk_context *, enum nk_symbol_type, struct nk_vec2 size)
nk_draw_image
NK_API void nk_draw_image(struct nk_command_buffer *, struct nk_rect, const struct nk_image *, struct nk_color)
nk_chart::h
float h
Definition: nuklear.h:5281
nk_str_at_char_const
NK_API const char * nk_str_at_char_const(const struct nk_str *, int pos)
nk_str_append_str_char
NK_API int nk_str_append_str_char(struct nk_str *, const char *)
nk_image::h
unsigned short h
Definition: nuklear.h:466
nk_text_undo_state::redo_point
short redo_point
Definition: nuklear.h:4265
nk_chart_begin_colored
NK_API int nk_chart_begin_colored(struct nk_context *, enum nk_chart_type, struct nk_color, struct nk_color active, int num, float min, float max)
NK_EDIT_CTRL_ENTER_NEWLINE
@ NK_EDIT_CTRL_ENTER_NEWLINE
Definition: nuklear.h:3425
nk_chart_push_slot
NK_API nk_flags nk_chart_push_slot(struct nk_context *, float, int)
nk_tooltip
NK_API void nk_tooltip(struct nk_context *, const char *)
NK_PANEL_POPUP
@ NK_PANEL_POPUP
Definition: nuklear.h:5257
nk_context::begin
struct nk_window * begin
Definition: nuklear.h:5602
nk_panel::row
struct nk_row_layout row
Definition: nuklear.h:5339
NK_COMMAND_LINE
@ NK_COMMAND_LINE
Definition: nuklear.h:4378
nk_input_begin
NK_API void nk_input_begin(struct nk_context *)
nk_combobox
NK_API void nk_combobox(struct nk_context *, const char **items, int count, int *selected, int item_height, struct nk_vec2 size)
NK_CURSOR_RESIZE_VERTICAL
@ NK_CURSOR_RESIZE_VERTICAL
Definition: nuklear.h:3597
nk_command_text::background
struct nk_color background
Definition: nuklear.h:4549
nk_command_circle_filled::x
short x
Definition: nuklear.h:4483
nk_window_show
NK_API void nk_window_show(struct nk_context *, const char *name, enum nk_show_states)
nk_clipboard
Definition: nuklear.h:4248
nk_window_get_size
NK_API struct nk_vec2 nk_window_get_size(const struct nk_context *)
nk_style_slider::cursor_size
struct nk_vec2 cursor_size
Definition: nuklear.h:4942
nk_stroke_polygon
NK_API void nk_stroke_polygon(struct nk_command_buffer *, float *, int point_count, float line_thickness, struct nk_color)
nk_command_circle_filled::h
unsigned short h
Definition: nuklear.h:4484
nk_radio_text
NK_API int nk_radio_text(struct nk_context *, const char *, int, int *active)
nk_command_scissor::h
unsigned short h
Definition: nuklear.h:4409
nk_style_window_header::label_hover
struct nk_color label_hover
Definition: nuklear.h:5166
nk_widget_has_mouse_click_down
NK_API int nk_widget_has_mouse_click_down(struct nk_context *, enum nk_buttons, int down)
nk_style_slider::userdata
nk_handle userdata
Definition: nuklear.h:4952
nk_style_selectable::text_hover
struct nk_color text_hover
Definition: nuklear.h:4896
nk_property_double
NK_API void nk_property_double(struct nk_context *, const char *name, double min, double *val, double max, double step, float inc_per_pixel)
nk_hsva_iv
NK_API struct nk_color nk_hsva_iv(const int *hsva)
nk_style_button::text_hover
struct nk_color text_hover
Definition: nuklear.h:4836
nk_textedit_paste
NK_API int nk_textedit_paste(struct nk_text_edit *, char const *, int len)
nk_popup_state::win
struct nk_window * win
Definition: nuklear.h:5372
nk_checkbox_flags_label
NK_API int nk_checkbox_flags_label(struct nk_context *, const char *, unsigned int *flags, unsigned int value)
nk_chart::slots
struct nk_chart_slot slots[NK_CHART_MAX_SLOT]
Definition: nuklear.h:5282
nk_command_arc
Definition: nuklear.h:4488
nk_style_combo::spacing
struct nk_vec2 spacing
Definition: nuklear.h:5122
nk_command_circle::x
short x
Definition: nuklear.h:4475
nk_str_insert_text_runes
NK_API int nk_str_insert_text_runes(struct nk_str *, int pos, const nk_rune *, int)
nk_rgb_fv
NK_API struct nk_color nk_rgb_fv(const float *rgb)
nk_radio_label
NK_API int nk_radio_label(struct nk_context *, const char *, int *active)
nk_style_progress::cursor_border_color
struct nk_color cursor_border_color
Definition: nuklear.h:4968
NK_EDIT_BOX
@ NK_EDIT_BOX
Definition: nuklear.h:3434
nk_colorf::g
float g
Definition: nuklear.h:459
nk_input::keyboard
struct nk_keyboard keyboard
Definition: nuklear.h:4627
NK_WINDOW_REMOVE_ROM
@ NK_WINDOW_REMOVE_ROM
Definition: nuklear.h:5367
nk_option_text
NK_API int nk_option_text(struct nk_context *, const char *, int, int active)
nk_combo_begin_color
NK_API int nk_combo_begin_color(struct nk_context *, struct nk_color color, struct nk_vec2 size)
NK_LAYOUT_TEMPLATE
@ NK_LAYOUT_TEMPLATE
Definition: nuklear.h:5294
nk_memory
Definition: nuklear.h:4118
nk_keyboard::text
char text[NK_INPUT_MAX]
Definition: nuklear.h:4622
nk_color::b
nk_byte b
Definition: nuklear.h:458
nk_option_label
NK_API int nk_option_label(struct nk_context *, const char *, int active)
NK_CONFIGURATION_STACK_TYPE
#define NK_CONFIGURATION_STACK_TYPE(prefix, name, type)
Definition: nuklear.h:5489
nk_context
Definition: nuklear.h:5570
nk_contextual_item_label
NK_API int nk_contextual_item_label(struct nk_context *, const char *, nk_flags align)
nk_text_edit::select_start
int select_start
Definition: nuklear.h:4288
NK_TEXT_RIGHT
@ NK_TEXT_RIGHT
Definition: nuklear.h:3084
nk_filter_decimal
NK_API int nk_filter_decimal(const struct nk_text_edit *, nk_rune unicode)
nk_widget
NK_API enum nk_widget_layout_states nk_widget(struct nk_rect *, const struct nk_context *)
nk_panel::max_x
float max_x
Definition: nuklear.h:5332
nk_style_push_color
NK_API int nk_style_push_color(struct nk_context *, struct nk_color *, struct nk_color)
nk_mouse::grabbed
unsigned char grabbed
Definition: nuklear.h:4612
NK_API
#define NK_API
Definition: nuklear.h:262
nk_style_property::label_normal
struct nk_color label_normal
Definition: nuklear.h:5058
nk_panel_set
nk_panel_set
Definition: nuklear.h:5263
nk_command_curve::end
struct nk_vec2i end
Definition: nuklear.h:4424
nk_buffer_free
NK_API void nk_buffer_free(struct nk_buffer *)
NK_RGBA
@ NK_RGBA
Definition: nuklear.h:478
nk_style_chart::border_color
struct nk_color border_color
Definition: nuklear.h:5084
nk_utf_len
NK_API int nk_utf_len(const char *, int byte_len)
NK_SYMBOL_RECT_OUTLINE
@ NK_SYMBOL_RECT_OUTLINE
Definition: nuklear.h:501
nk_style_window::tooltip_border_color
struct nk_color tooltip_border_color
Definition: nuklear.h:5187
NK_LEN
#define NK_LEN(a)
Definition: nuklear.h:5620
nk_input_motion
NK_API void nk_input_motion(struct nk_context *, int x, int y)
NK_WINDOW_TITLE
@ NK_WINDOW_TITLE
Definition: nuklear.h:1458
nk_panel::border
float border
Definition: nuklear.h:5335
nk_str_len
NK_API int nk_str_len(struct nk_str *)
NK_PANEL_WINDOW
@ NK_PANEL_WINDOW
Definition: nuklear.h:5255
nk_style::edit
struct nk_style_edit edit
Definition: nuklear.h:5230
nk_command_polygon_filled::color
struct nk_color color
Definition: nuklear.h:4515
nk_style_slider::hover
struct nk_style_item hover
Definition: nuklear.h:4921
nk_command_rect_filled::y
short y
Definition: nuklear.h:4441
nk_command_rect::h
unsigned short h
Definition: nuklear.h:4434
NK_MIN
#define NK_MIN(a, b)
Definition: nuklear.h:302
nk_button_symbol_label
NK_API int nk_button_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags text_alignment)
nk_rgba_hex
NK_API struct nk_color nk_rgba_hex(const char *rgb)
nk_text_undo_record::delete_length
short delete_length
Definition: nuklear.h:4257
nk_button_image
NK_API int nk_button_image(struct nk_context *, struct nk_image img)
nk_input_has_mouse_click
NK_API int nk_input_has_mouse_click(const struct nk_input *, enum nk_buttons)
nk_button_image_label_styled
NK_API int nk_button_image_label_styled(struct nk_context *, const struct nk_style_button *, struct nk_image img, const char *, nk_flags text_alignment)
nk_vec2i
Definition: nuklear.h:461
nk_text_undo_state::redo_char_point
short redo_char_point
Definition: nuklear.h:4267
nk_orientation
nk_orientation
Definition: nuklear.h:473
NK_TEXT_ALIGN_RIGHT
@ NK_TEXT_ALIGN_RIGHT
Definition: nuklear.h:3076
nk_text_edit::has_preferred_x
unsigned char has_preferred_x
Definition: nuklear.h:4293
NK_UINT16
#define NK_UINT16
Definition: nuklear.h:351
nk_str::buffer
struct nk_buffer buffer
Definition: nuklear.h:4166
nk_tooltip_end
NK_API void nk_tooltip_end(struct nk_context *)
nk_color_hsva_fv
NK_API void nk_color_hsva_fv(float *hsva_out, struct nk_color)
NK_KEY_UP
@ NK_KEY_UP
Definition: nuklear.h:747
nk_hsva_fv
NK_API struct nk_color nk_hsva_fv(const float *hsva)
nk_input_button
NK_API void nk_input_button(struct nk_context *, enum nk_buttons, int x, int y, int down)
NK_COLOR_BUTTON
@ NK_COLOR_BUTTON
Definition: nuklear.h:3567
nk_menu_begin_symbol_label
NK_API int nk_menu_begin_symbol_label(struct nk_context *, const char *, nk_flags align, enum nk_symbol_type, struct nk_vec2 size)
NK_LAYOUT_STATIC_FREE
@ NK_LAYOUT_STATIC_FREE
Definition: nuklear.h:5292
nk_button_push_behavior
NK_API int nk_button_push_behavior(struct nk_context *, enum nk_button_behavior)
nk_color_hsva_iv
NK_API void nk_color_hsva_iv(int *hsva_out, struct nk_color)
nk_spacing
NK_API void nk_spacing(struct nk_context *, int cols)
nk_input_any_mouse_click_in_rect
NK_API int nk_input_any_mouse_click_in_rect(const struct nk_input *, struct nk_rect)
nk_memory::ptr
void * ptr
Definition: nuklear.h:4118
nk_page::size
unsigned int size
Definition: nuklear.h:5554
nk_image::handle
nk_handle handle
Definition: nuklear.h:466
nk_image_is_subimage
NK_API int nk_image_is_subimage(const struct nk_image *img)
nk_input_key
NK_API void nk_input_key(struct nk_context *, enum nk_keys, int down)
nk_command_rect_multi_color::h
unsigned short h
Definition: nuklear.h:4449
nk_page_element
Definition: nuklear.h:5547
nk_style_tab::text
struct nk_color text
Definition: nuklear.h:5129
nk_context::use_pool
int use_pool
Definition: nuklear.h:5600
nk_property_state::state
int state
Definition: nuklear.h:5406
nk_buffer_clear
NK_API void nk_buffer_clear(struct nk_buffer *)
nk_style_pop_vec2
NK_API int nk_style_pop_vec2(struct nk_context *)
nk_style_combo::rounding
float rounding
Definition: nuklear.h:5119
nk_window_get_height
NK_API float nk_window_get_height(const struct nk_context *)
nk_context::text_edit
struct nk_text_edit text_edit
Definition: nuklear.h:5594
nk_propertyf
NK_API float nk_propertyf(struct nk_context *, const char *name, float min, float val, float max, float step, float inc_per_pixel)
nk_window_get_width
NK_API float nk_window_get_width(const struct nk_context *)
nk_chart_slot::min
float min
Definition: nuklear.h:5273
NK_COMMAND_RECT_FILLED
@ NK_COMMAND_RECT_FILLED
Definition: nuklear.h:4381
nk_text_undo_state::undo_char_point
short undo_char_point
Definition: nuklear.h:4266
nk_configuration_stacks::floats
struct nk_config_stack_float floats
Definition: nuklear.h:5519
nk_command_buffer::base
struct nk_buffer * base
Definition: nuklear.h:4564
nk_panel::clip
struct nk_rect clip
Definition: nuklear.h:5337
NK_TEXT_ALIGN_LEFT
@ NK_TEXT_ALIGN_LEFT
Definition: nuklear.h:3074
nk_combo_close
NK_API void nk_combo_close(struct nk_context *)
nk_menu_end
NK_API void nk_menu_end(struct nk_context *)
nk_style_slider::bar_normal
struct nk_color bar_normal
Definition: nuklear.h:4926
NK_CURSOR_RESIZE_HORIZONTAL
@ NK_CURSOR_RESIZE_HORIZONTAL
Definition: nuklear.h:3598
nk_fill_rect
NK_API void nk_fill_rect(struct nk_command_buffer *, struct nk_rect, float rounding, struct nk_color)
nk_convert_config::vertex_alignment
nk_size vertex_alignment
Definition: nuklear.h:1165
nk_menu_state
Definition: nuklear.h:5321
nk_style_item_data::image
struct nk_image image
Definition: nuklear.h:4812
nk_style_property::normal
struct nk_style_item normal
Definition: nuklear.h:5052
nk_selectable_label
NK_API int nk_selectable_label(struct nk_context *, const char *, nk_flags align, int *value)
nk_edit_flags
nk_edit_flags
Definition: nuklear.h:3416
nk_str_at_const
NK_API const char * nk_str_at_const(const struct nk_str *, int pos, nk_rune *unicode, int *len)
NK_ANTI_ALIASING_ON
@ NK_ANTI_ALIASING_ON
Definition: nuklear.h:1143
nk_memory::size
nk_size size
Definition: nuklear.h:4118
nk_style_progress::cursor_normal
struct nk_style_item cursor_normal
Definition: nuklear.h:4965
nk_recti::h
short h
Definition: nuklear.h:463
nk_command_polygon::points
struct nk_vec2i points[1]
Definition: nuklear.h:4510
nk_menu_begin_image_text
NK_API int nk_menu_begin_image_text(struct nk_context *, const char *, int, nk_flags align, struct nk_image, struct nk_vec2 size)
nk_style_window::popup_border
float popup_border
Definition: nuklear.h:5196
nk_mouse::pos
struct nk_vec2 pos
Definition: nuklear.h:4607
nk_command_text
Definition: nuklear.h:4546
nk_property_state::select_end
int select_end
Definition: nuklear.h:5402
nk_style_button::draw_end
void(* draw_end)(struct nk_command_buffer *, nk_handle userdata)
Definition: nuklear.h:4850
NK_WIDGET_STATE_ENTERED
@ NK_WIDGET_STATE_ENTERED
Definition: nuklear.h:3050
nk_style_button::border_color
struct nk_color border_color
Definition: nuklear.h:4831
nk_text_edit::cursor_at_end_of_line
unsigned char cursor_at_end_of_line
Definition: nuklear.h:4291
nk_allocator::free
nk_plugin_free free
Definition: nuklear.h:492
nk_hsv_iv
NK_API struct nk_color nk_hsv_iv(const int *hsv)
nk_window::popup
struct nk_popup_state popup
Definition: nuklear.h:5423
nk_convert_config::vertex_layout
const struct nk_draw_vertex_layout_element * vertex_layout
Definition: nuklear.h:1163
nk_style_slider
Definition: nuklear.h:4918
nk_menu_begin_symbol_text
NK_API int nk_menu_begin_symbol_text(struct nk_context *, const char *, int, nk_flags align, enum nk_symbol_type, struct nk_vec2 size)
nk_check_flags_text
NK_API unsigned nk_check_flags_text(struct nk_context *, const char *, int, unsigned int flags, unsigned int value)
nk_tree_pop
NK_API void nk_tree_pop(struct nk_context *)
NK_CHART_COLUMN
@ NK_CHART_COLUMN
Definition: nuklear.h:476
NK_STYLE_ITEM_STACK_SIZE
#define NK_STYLE_ITEM_STACK_SIZE
Definition: nuklear.h:5470
nk_window_get_scroll
NK_API void nk_window_get_scroll(struct nk_context *, nk_uint *offset_x, nk_uint *offset_y)
nk_table::keys
nk_hash keys[NK_VALUE_PAGE_CAPACITY]
Definition: nuklear.h:5536
nk_command_rect::x
short x
Definition: nuklear.h:4433
nk_buffer::size
nk_size size
Definition: nuklear.h:4136
nk_style_button::normal
struct nk_style_item normal
Definition: nuklear.h:4828
nk_row_layout::index
int index
Definition: nuklear.h:5299
nk_convert_config::vertex_size
nk_size vertex_size
Definition: nuklear.h:1164
nk_group_scrolled_offset_begin
NK_API int nk_group_scrolled_offset_begin(struct nk_context *, nk_uint *x_offset, nk_uint *y_offset, const char *title, nk_flags flags)
NK_DOWN
@ NK_DOWN
Definition: nuklear.h:470
nk_text_edit::initialized
unsigned char initialized
Definition: nuklear.h:4292
nk_row_layout::item_height
float item_height
Definition: nuklear.h:5305
nk__begin
NK_API const struct nk_command * nk__begin(struct nk_context *)
nk_style_hide_cursor
NK_API void nk_style_hide_cursor(struct nk_context *)
nk_str_insert_text_utf8
NK_API int nk_str_insert_text_utf8(struct nk_str *, int pos, const char *, int)
NK_WIDGET_STATE_ACTIVED
@ NK_WIDGET_STATE_ACTIVED
Definition: nuklear.h:3052
nk_window::scrollbar_hiding_timer
float scrollbar_hiding_timer
Definition: nuklear.h:5419
nk_plugin_alloc
void *(* nk_plugin_alloc)(nk_handle, void *old, nk_size)
Definition: nuklear.h:483
nk_style_selectable::image_padding
struct nk_vec2 image_padding
Definition: nuklear.h:4910
nk_panel::header_height
float header_height
Definition: nuklear.h:5334
nk_style_combo::symbol_active
struct nk_color symbol_active
Definition: nuklear.h:5109
nk_command_rect::y
short y
Definition: nuklear.h:4433
nk_selectable_text
NK_API int nk_selectable_text(struct nk_context *, const char *, int, nk_flags align, int *value)
nk_convert_config::arc_segment_count
unsigned arc_segment_count
Definition: nuklear.h:1160
nk_str_remove_runes
NK_API void nk_str_remove_runes(struct nk_str *str, int len)
nk_popup_state::active
int active
Definition: nuklear.h:5376
nk_input_end
NK_API void nk_input_end(struct nk_context *)
nk_window_set_bounds
NK_API void nk_window_set_bounds(struct nk_context *, const char *name, struct nk_rect bounds)
nk_mouse::buttons
struct nk_mouse_button buttons[NK_BUTTON_MAX]
Definition: nuklear.h:4606
nk_tree_image_push_hashed
NK_API int nk_tree_image_push_hashed(struct nk_context *, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states initial_state, const char *hash, int len, int seed)
nk_style_edit::cursor_text_hover
struct nk_color cursor_text_hover
Definition: nuklear.h:5028
nk_widget_bounds
NK_API struct nk_rect nk_widget_bounds(struct nk_context *)
nk_colorf::r
float r
Definition: nuklear.h:459
nk_chart_slot::count
int count
Definition: nuklear.h:5274
nk_style_window_header::minimize_symbol
enum nk_symbol_type minimize_symbol
Definition: nuklear.h:5161
nk_allocation_type
nk_allocation_type
Definition: nuklear.h:4102
nk_edit_events
nk_edit_events
Definition: nuklear.h:3437
nk_style_progress
Definition: nuklear.h:4957
nk_command_text::foreground
struct nk_color foreground
Definition: nuklear.h:4550
nk_stroke_rect
NK_API void nk_stroke_rect(struct nk_command_buffer *, struct nk_rect, float rounding, float line_thickness, struct nk_color)
nk_style_scrollbar::cursor_normal
struct nk_style_item cursor_normal
Definition: nuklear.h:4991
nk_rect_pos
NK_API struct nk_vec2 nk_rect_pos(struct nk_rect)
nk_window::name_string
char name_string[NK_WINDOW_MAX_NAME]
Definition: nuklear.h:5412
nk_panel::chart
struct nk_chart chart
Definition: nuklear.h:5340
nk_combo_begin_image_text
NK_API int nk_combo_begin_image_text(struct nk_context *, const char *selected, int, struct nk_image, struct nk_vec2 size)
NK_COLOR_SELECT
@ NK_COLOR_SELECT
Definition: nuklear.h:3573
nk_style_edit::scrollbar
struct nk_style_scrollbar scrollbar
Definition: nuklear.h:5022
nk_command_triangle_filled::header
struct nk_command header
Definition: nuklear.h:4466
nk_buffer::marker
struct nk_buffer_marker marker[NK_BUFFER_MAX]
Definition: nuklear.h:4120
nk_panel::at_y
float at_y
Definition: nuklear.h:5332
nk_command_triangle::c
struct nk_vec2i c
Definition: nuklear.h:4461
nk_user_font
Definition: nuklear.h:3915
nk_window::bounds
struct nk_rect bounds
Definition: nuklear.h:5415
nk_rgb_f
NK_API struct nk_color nk_rgb_f(float r, float g, float b)
nk_buffer::type
enum nk_allocation_type type
Definition: nuklear.h:4124
nk_style::selectable
struct nk_style_selectable selectable
Definition: nuklear.h:5226
nk_cursor::offset
struct nk_vec2 size offset
Definition: nuklear.h:467
nk_style_selectable::text_pressed_active
struct nk_color text_pressed_active
Definition: nuklear.h:4902
NK_CURSOR_ARROW
@ NK_CURSOR_ARROW
Definition: nuklear.h:3594
nk_memory_status
Definition: nuklear.h:4093
nk_style_scrollbar::border_color
struct nk_color border_color
Definition: nuklear.h:4988
nk_style_combo::symbol_hover
struct nk_color symbol_hover
Definition: nuklear.h:5108
nk_button_pop_behavior
NK_API int nk_button_pop_behavior(struct nk_context *)
nk_chart_slot::max
float max
Definition: nuklear.h:5273
nk_list_view::scroll_value
nk_uint scroll_value
Definition: nuklear.h:3033
nk_str_get_const
NK_API const char * nk_str_get_const(const struct nk_str *)
nk_layout_row
NK_API void nk_layout_row(struct nk_context *, enum nk_layout_format, float height, int cols, const float *ratio)
nk_filter_oct
NK_API int nk_filter_oct(const struct nk_text_edit *, nk_rune unicode)
nk_style_button::userdata
nk_handle userdata
Definition: nuklear.h:4848
nk_style_edit::cursor_normal
struct nk_color cursor_normal
Definition: nuklear.h:5025
nk_propertyd
NK_API double nk_propertyd(struct nk_context *, const char *name, double min, double val, double max, double step, float inc_per_pixel)
nk_rgb_cf
NK_API struct nk_color nk_rgb_cf(struct nk_colorf c)
nk_command_type
nk_command_type
Definition: nuklear.h:4375
nk_command_buffer
Definition: nuklear.h:4563
nk_hsva_colorf
NK_API struct nk_colorf nk_hsva_colorf(float h, float s, float v, float a)
nk_textedit_free
NK_API void nk_textedit_free(struct nk_text_edit *)
NK_VALUE_PAGE_CAPACITY
#define NK_VALUE_PAGE_CAPACITY
Definition: nuklear.h:5530
nk_style_toggle::hover
struct nk_style_item hover
Definition: nuklear.h:4856
nk_prog
NK_API nk_size nk_prog(struct nk_context *, nk_size cur, nk_size max, int modifyable)
NK_BUFFER_FRONT
@ NK_BUFFER_FRONT
Definition: nuklear.h:4108
NK_INTERN
#define NK_INTERN
Definition: nuklear.h:273
nk_style_property::dec_button
struct nk_style_button dec_button
Definition: nuklear.h:5073
nk_slider_int
NK_API int nk_slider_int(struct nk_context *, int min, int *val, int max, int step)
NK_WINDOW_MOVABLE
@ NK_WINDOW_MOVABLE
Definition: nuklear.h:1453
nk_style_combo::button
struct nk_style_button button
Definition: nuklear.h:5112
nk_edit_state::seq
unsigned int seq
Definition: nuklear.h:5385
nk_combo_begin_image_label
NK_API int nk_combo_begin_image_label(struct nk_context *, const char *selected, struct nk_image, struct nk_vec2 size)
nk_widget_height
NK_API float nk_widget_height(struct nk_context *)
nk_convert_config::global_alpha
float global_alpha
Definition: nuklear.h:1156
nk_rect
Definition: nuklear.h:462
nk_style_property::userdata
nk_handle userdata
Definition: nuklear.h:5076
nk_hsv_f
NK_API struct nk_color nk_hsv_f(float h, float s, float v)
nk_ptr_add
#define nk_ptr_add(t, p, i)
Definition: nuklear.h:5635
NK_COLOR_BUTTON_ACTIVE
@ NK_COLOR_BUTTON_ACTIVE
Definition: nuklear.h:3569
nk_style_toggle::cursor_hover
struct nk_style_item cursor_hover
Definition: nuklear.h:4862
NK_COMMAND_CURVE
@ NK_COMMAND_CURVE
Definition: nuklear.h:4379
NK_COLOR_HEADER
@ NK_COLOR_HEADER
Definition: nuklear.h:3565
nk_style::window
struct nk_style_window window
Definition: nuklear.h:5236
nk_command_polygon_filled
Definition: nuklear.h:4513
nk_popup_state
Definition: nuklear.h:5371
nk_pool::size
nk_size size
Definition: nuklear.h:5566
NK_WINDOW_SCALE_LEFT
@ NK_WINDOW_SCALE_LEFT
Definition: nuklear.h:1461
NK_EDIT_NO_CURSOR
@ NK_EDIT_NO_CURSOR
Definition: nuklear.h:3422
nk_str::len
int len
Definition: nuklear.h:4167
nk_edit_string
NK_API nk_flags nk_edit_string(struct nk_context *, nk_flags, char *buffer, int *len, int max, nk_plugin_filter)
nk_buffer_marker::offset
nk_size offset
Definition: nuklear.h:4115
nk_textedit_delete
NK_API void nk_textedit_delete(struct nk_text_edit *, int where, int len)
nk_panel::flags
nk_flags flags
Definition: nuklear.h:5328
nk_slide_float
NK_API float nk_slide_float(struct nk_context *, float min, float val, float max, float step)
nk_command_rect::header
struct nk_command header
Definition: nuklear.h:4430
nk_hash
nk_uint nk_hash
Definition: nuklear.h:409
nk_slide_int
NK_API int nk_slide_int(struct nk_context *, int min, int val, int max, int step)
nk_selectable_image_text
NK_API int nk_selectable_image_text(struct nk_context *, struct nk_image, const char *, int, nk_flags align, int *value)
nk_text_edit::preferred_x
float preferred_x
Definition: nuklear.h:4297
nk_context::current
struct nk_window * current
Definition: nuklear.h:5605
nk_style_selectable::text_background
struct nk_color text_background
Definition: nuklear.h:4903
nk_checkbox_label
NK_API int nk_checkbox_label(struct nk_context *, const char *, int *active)
nk_input_is_mouse_pressed
NK_API int nk_input_is_mouse_pressed(const struct nk_input *, enum nk_buttons)
NK_KEY_PASTE
@ NK_KEY_PASTE
Definition: nuklear.h:746
NK_KEY_TAB
@ NK_KEY_TAB
Definition: nuklear.h:742
nk_command_buffer::use_clipping
int use_clipping
Definition: nuklear.h:4566
nk_command_image::y
short y
Definition: nuklear.h:4530
nk_command_custom
Definition: nuklear.h:4538
nk_vec2_add
#define nk_vec2_add(a, b)
Definition: nuklear.h:5631
nk_command_rect_filled::header
struct nk_command header
Definition: nuklear.h:4439
nk_style_item_color
NK_API struct nk_style_item nk_style_item_color(struct nk_color)
nk_window_get_bounds
NK_API struct nk_rect nk_window_get_bounds(const struct nk_context *ctx)
nk_slider_float
NK_API int nk_slider_float(struct nk_context *, float min, float *val, float max, float step)
nk_false
@ nk_false
Definition: nuklear.h:457
nk_selectable_symbol_text
NK_API int nk_selectable_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags align, int *value)
nk_style_selectable
Definition: nuklear.h:4883
nk_text_edit::select_end
int select_end
Definition: nuklear.h:4289
NK_CURSOR_RESIZE_TOP_LEFT_DOWN_RIGHT
@ NK_CURSOR_RESIZE_TOP_LEFT_DOWN_RIGHT
Definition: nuklear.h:3599
nk_style::menu_button
struct nk_style_button menu_button
Definition: nuklear.h:5223
nk_row_layout::height
float height
Definition: nuklear.h:5300
nk_style_window_header::maximize_symbol
enum nk_symbol_type maximize_symbol
Definition: nuklear.h:5162
NK_WINDOW_NOT_INTERACTIVE
@ NK_WINDOW_NOT_INTERACTIVE
Definition: nuklear.h:5359
nk_handle_ptr
NK_API nk_handle nk_handle_ptr(void *)
nk_menu_begin_image
NK_API int nk_menu_begin_image(struct nk_context *, const char *, struct nk_image, struct nk_vec2 size)
nk_style_slider::cursor_hover
struct nk_style_item cursor_hover
Definition: nuklear.h:4933
nk_color_format
nk_color_format
Definition: nuklear.h:478
nk_input_is_key_released
NK_API int nk_input_is_key_released(const struct nk_input *, enum nk_keys)
NK_WIDGET_VALID
@ NK_WIDGET_VALID
Definition: nuklear.h:3044
nk_command_triangle::header
struct nk_command header
Definition: nuklear.h:4457
nk_style_window::popup_padding
struct nk_vec2 popup_padding
Definition: nuklear.h:5206
nk_chart::w
float w
Definition: nuklear.h:5281
nk_convert_config::shape_AA
enum nk_anti_aliasing shape_AA
Definition: nuklear.h:1158
NK_COLOR_SLIDER_CURSOR
@ NK_COLOR_SLIDER_CURSOR
Definition: nuklear.h:3576
nk_command_arc::line_thickness
unsigned short line_thickness
Definition: nuklear.h:4492
nk_mouse
Definition: nuklear.h:4605
nk_chart_type
nk_chart_type
Definition: nuklear.h:476
NK_BETWEEN
#define NK_BETWEEN(x, a, b)
Definition: nuklear.h:5622
nk_begin_titled
NK_API int nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, struct nk_rect bounds, nk_flags flags)
nk_command_custom::y
short y
Definition: nuklear.h:4540
nk_command_polygon::header
struct nk_command header
Definition: nuklear.h:4506
nk_text_edit::scrollbar
struct nk_vec2 scrollbar
Definition: nuklear.h:4285
nk_text_edit::active
unsigned char active
Definition: nuklear.h:4295
nk_group_begin
NK_API int nk_group_begin(struct nk_context *, const char *title, nk_flags)
nk_textedit_undo
NK_API void nk_textedit_undo(struct nk_text_edit *)
nk_strfilter
NK_API int nk_strfilter(const char *text, const char *regexp)
nk_image_handle
NK_API struct nk_image nk_image_handle(nk_handle)
nk_style_window_header::align
enum nk_style_header_align align
Definition: nuklear.h:5170
nk_style_window::scrollbar_size
struct nk_vec2 scrollbar_size
Definition: nuklear.h:5201
nk_style
Definition: nuklear.h:5213
nk_clear
NK_API void nk_clear(struct nk_context *)
nk_style::cursor_active
const struct nk_cursor * cursor_active
Definition: nuklear.h:5216
nk_style_toggle::normal
struct nk_style_item normal
Definition: nuklear.h:4855
nk_style_item::data
union nk_style_item_data data
Definition: nuklear.h:4818
nk_context::memory
struct nk_buffer memory
Definition: nuklear.h:5574
nk_style_tab::node_maximize_button
struct nk_style_button node_maximize_button
Definition: nuklear.h:5134
nk_input_is_mouse_hovering_rect
NK_API int nk_input_is_mouse_hovering_rect(const struct nk_input *, struct nk_rect)
NK_COMMAND_TEXT
@ NK_COMMAND_TEXT
Definition: nuklear.h:4392
nk_layout_ratio_from_pixel
NK_API float nk_layout_ratio_from_pixel(struct nk_context *, float pixel_width)
nk_command_arc_filled::cy
short cy
Definition: nuklear.h:4499
NK_WINDOW_ROM
@ NK_WINDOW_ROM
Definition: nuklear.h:5357
nk_style_selectable::hover
struct nk_style_item hover
Definition: nuklear.h:4886
nk_context::style
struct nk_style style
Definition: nuklear.h:5573
NK_KEY_TEXT_INSERT_MODE
@ NK_KEY_TEXT_INSERT_MODE
Definition: nuklear.h:752
nk_button_text
NK_API int nk_button_text(struct nk_context *, const char *title, int len)
nk_handle_id
NK_API nk_handle nk_handle_id(int)
nk_str_append_str_runes
NK_API int nk_str_append_str_runes(struct nk_str *, const nk_rune *)
nk_chart_begin
NK_API int nk_chart_begin(struct nk_context *, enum nk_chart_type, int num, float min, float max)
nk_combo_item_image_label
NK_API int nk_combo_item_image_label(struct nk_context *, struct nk_image, const char *, nk_flags alignment)
nk_window_set_position
NK_API void nk_window_set_position(struct nk_context *, const char *name, struct nk_vec2 pos)
NK_UINT8
#define NK_UINT8
Definition: nuklear.h:345
nk_style_chart::padding
struct nk_vec2 padding
Definition: nuklear.h:5091
nk_style_window::tooltip_padding
struct nk_vec2 tooltip_padding
Definition: nuklear.h:5210
nk_triangle_from_direction
NK_API void nk_triangle_from_direction(struct nk_vec2 *result, struct nk_rect r, float pad_x, float pad_y, enum nk_heading)
nk_str_free
NK_API void nk_str_free(struct nk_str *)
nk_edit_buffer
NK_API nk_flags nk_edit_buffer(struct nk_context *, nk_flags, struct nk_text_edit *, nk_plugin_filter)
nk_window_show_if
NK_API void nk_window_show_if(struct nk_context *, const char *name, enum nk_show_states, int cond)
nk_menubar_begin
NK_API void nk_menubar_begin(struct nk_context *)
nk_command_image::img
struct nk_image img
Definition: nuklear.h:4532
NK_PANEL_GROUP
@ NK_PANEL_GROUP
Definition: nuklear.h:5256
nk_panel::at_x
float at_x
Definition: nuklear.h:5332
nk_strmatch_fuzzy_string
NK_API int nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score)
nk_short
NK_INT16 nk_short
Definition: nuklear.h:402
nk_chart_slot::highlight
struct nk_color highlight
Definition: nuklear.h:5272
NK_EDIT_NO_HORIZONTAL_SCROLL
@ NK_EDIT_NO_HORIZONTAL_SCROLL
Definition: nuklear.h:3426
nk_style_edit::cursor_hover
struct nk_color cursor_hover
Definition: nuklear.h:5026
NK_MINIMIZED
@ NK_MINIMIZED
Definition: nuklear.h:474
nk_menu_begin_label
NK_API int nk_menu_begin_label(struct nk_context *, const char *, nk_flags align, struct nk_vec2 size)
nk_filter_float
NK_API int nk_filter_float(const struct nk_text_edit *, nk_rune unicode)
NK_COLOR_SLIDER
@ NK_COLOR_SLIDER
Definition: nuklear.h:3575
nk_edit_state::old
unsigned int old
Definition: nuklear.h:5386
NK_KEY_DOWN
@ NK_KEY_DOWN
Definition: nuklear.h:748
NK_SYMBOL_MAX
@ NK_SYMBOL_MAX
Definition: nuklear.h:508
nk_style_toggle::spacing
float spacing
Definition: nuklear.h:4874
nk_style::text
struct nk_style_text text
Definition: nuklear.h:5220
nk_layout_row_template_end
NK_API void nk_layout_row_template_end(struct nk_context *)
nk_group_begin_titled
NK_API int nk_group_begin_titled(struct nk_context *, const char *name, const char *title, nk_flags)
nk_command_arc_filled::header
struct nk_command header
Definition: nuklear.h:4498
nk_recti::y
short y
Definition: nuklear.h:463
nk_property_state::seq
unsigned int seq
Definition: nuklear.h:5404
NK_EDIT_ALLOW_TAB
@ NK_EDIT_ALLOW_TAB
Definition: nuklear.h:3421
nk_window_flags
nk_window_flags
Definition: nuklear.h:5353
NK_SYMBOL_CIRCLE_SOLID
@ NK_SYMBOL_CIRCLE_SOLID
Definition: nuklear.h:498
nk_window_is_active
NK_API int nk_window_is_active(struct nk_context *, const char *)
nk_style_slider::dec_symbol
enum nk_symbol_type dec_symbol
Definition: nuklear.h:4949
NK_ANTI_ALIASING_OFF
@ NK_ANTI_ALIASING_OFF
Definition: nuklear.h:1143
nk_command_text::font
const struct nk_user_font * font
Definition: nuklear.h:4548
NK_COMMAND_CIRCLE
@ NK_COMMAND_CIRCLE
Definition: nuklear.h:4383
nk_popup_state::combo_count
unsigned combo_count
Definition: nuklear.h:5377
nk_combo_string
NK_API int nk_combo_string(struct nk_context *, const char *items_separated_by_zeros, int selected, int count, int item_height, struct nk_vec2 size)
nk_menu_state::w
float w
Definition: nuklear.h:5322
nk_group_scrolled_begin
NK_API int nk_group_scrolled_begin(struct nk_context *, struct nk_scroll *off, const char *title, nk_flags)
nk_rect::x
float x
Definition: nuklear.h:462
nk_command_rect_multi_color::header
struct nk_command header
Definition: nuklear.h:4447
nk_list_view_begin
NK_API int nk_list_view_begin(struct nk_context *, struct nk_list_view *out, const char *id, nk_flags, int row_height, int row_count)
nk_color_hsva_b
NK_API void nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a, struct nk_color)
NK_TEXT_ALIGN_TOP
@ NK_TEXT_ALIGN_TOP
Definition: nuklear.h:3077
nk_style_slider::draw_begin
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4953
NK_MODIFIABLE
@ NK_MODIFIABLE
Definition: nuklear.h:472
nk_plot_function
NK_API void nk_plot_function(struct nk_context *, enum nk_chart_type, void *userdata, float(*value_getter)(void *user, int index), int count, int offset)
NK_COLOR_SCROLLBAR_CURSOR
@ NK_COLOR_SCROLLBAR_CURSOR
Definition: nuklear.h:3587
nk_panel
Definition: nuklear.h:5326
nk_style::progress
struct nk_style_progress progress
Definition: nuklear.h:5228
nk_input_is_mouse_down
NK_API int nk_input_is_mouse_down(const struct nk_input *, enum nk_buttons)
nk_style_selectable::draw_begin
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4914
NK_WINDOW_SCALABLE
@ NK_WINDOW_SCALABLE
Definition: nuklear.h:1454
nk_style_toggle::text_alignment
nk_flags text_alignment
Definition: nuklear.h:4869
nk_command_arc_filled::a
float a[2]
Definition: nuklear.h:4501
NK_TEXTEDIT_UNDOSTATECOUNT
#define NK_TEXTEDIT_UNDOSTATECOUNT
Definition: nuklear.h:4240
nk_plugin_copy
void(* nk_plugin_copy)(nk_handle, const char *, int len)
Definition: nuklear.h:487
nk_input_unicode
NK_API void nk_input_unicode(struct nk_context *, nk_rune)
nk_property_state::active
int active
Definition: nuklear.h:5397
nk_button_symbol_text_styled
NK_API int nk_button_symbol_text_styled(struct nk_context *, const struct nk_style_button *, enum nk_symbol_type, const char *, int, nk_flags alignment)
nk_row_layout::templates
float templates[NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS]
Definition: nuklear.h:5310
NK_INPUT_MAX
#define NK_INPUT_MAX
Definition: nuklear.h:237
nk_style_toggle::padding
struct nk_vec2 padding
Definition: nuklear.h:4872
nk_command_triangle::a
struct nk_vec2i a
Definition: nuklear.h:4459
nk_recti
NK_API struct nk_rect nk_recti(int x, int y, int w, int h)
nk_command_triangle::line_thickness
unsigned short line_thickness
Definition: nuklear.h:4458
nk_style_load_all_cursors
NK_API void nk_style_load_all_cursors(struct nk_context *, struct nk_cursor *)
NK_BUTTON_REPEATER
@ NK_BUTTON_REPEATER
Definition: nuklear.h:471
nk_style_button::active
struct nk_style_item active
Definition: nuklear.h:4830
nk_style_push_style_item
NK_API int nk_style_push_style_item(struct nk_context *, struct nk_style_item *, struct nk_style_item)
nk_button_symbol
NK_API int nk_button_symbol(struct nk_context *, enum nk_symbol_type)
ctx
struct nk_context * ctx
Definition: main.cpp:54
nk_property_state
Definition: nuklear.h:5396
nk_popup_state::header
struct nk_rect header
Definition: nuklear.h:5380
nk_row_layout
Definition: nuklear.h:5297
NK_BUFFER_BACK
@ NK_BUFFER_BACK
Definition: nuklear.h:4109
nk_popup_buffer::last
nk_size last
Definition: nuklear.h:5316
nk_configuration_stacks
Definition: nuklear.h:5517
NK_CONVERT_ELEMENT_BUFFER_FULL
@ NK_CONVERT_ELEMENT_BUFFER_FULL
Definition: nuklear.h:1149
NK_SYMBOL_TRIANGLE_RIGHT
@ NK_SYMBOL_TRIANGLE_RIGHT
Definition: nuklear.h:505
nk_style_edit::selected_normal
struct nk_color selected_normal
Definition: nuklear.h:5036
NK_COLOR_SCROLLBAR_CURSOR_HOVER
@ NK_COLOR_SCROLLBAR_CURSOR_HOVER
Definition: nuklear.h:3588
nk_fill_triangle
NK_API void nk_fill_triangle(struct nk_command_buffer *, float x0, float y0, float x1, float y1, float x2, float y2, struct nk_color)
nk_style_edit::row_padding
float row_padding
Definition: nuklear.h:5047
nk_property_state::cursor
int cursor
Definition: nuklear.h:5400
nk_vec2_len_sqr
#define nk_vec2_len_sqr(a)
Definition: nuklear.h:5632
nk_style_property::sym_left
enum nk_symbol_type sym_left
Definition: nuklear.h:5063
nk_command_circle::y
short y
Definition: nuklear.h:4475
nk_str_get
NK_API char * nk_str_get(struct nk_str *)
nk_command_arc::r
unsigned short r
Definition: nuklear.h:4491
nk_property_state::prev
int prev
Definition: nuklear.h:5397
nk_selectable_symbol_label
NK_API int nk_selectable_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags align, int *value)
NK_BUTTON_DOUBLE
@ NK_BUTTON_DOUBLE
Definition: nuklear.h:775
nk_text_undo_state::undo_rec
struct nk_text_undo_record undo_rec[NK_TEXTEDIT_UNDOSTATECOUNT]
Definition: nuklear.h:4262
nk_style_push_vec2
NK_API int nk_style_push_vec2(struct nk_context *, struct nk_vec2 *, struct nk_vec2)
nk_style_button::padding
struct nk_vec2 padding
Definition: nuklear.h:4843
nk_popup_set_scroll
NK_API void nk_popup_set_scroll(struct nk_context *, nk_uint offset_x, nk_uint offset_y)
nk_command_circle::line_thickness
unsigned short line_thickness
Definition: nuklear.h:4476
nk_buffer_info
NK_API void nk_buffer_info(struct nk_memory_status *, struct nk_buffer *)
nk_tree_element_push_hashed
NK_API int nk_tree_element_push_hashed(struct nk_context *, enum nk_tree_type, const char *title, enum nk_collapse_states initial_state, int *selected, const char *hash, int len, int seed)
nk_style_window
Definition: nuklear.h:5176
nk_menu_begin_symbol
NK_API int nk_menu_begin_symbol(struct nk_context *, const char *, enum nk_symbol_type, struct nk_vec2 size)
NK_EDIT_SIG_ENTER
@ NK_EDIT_SIG_ENTER
Definition: nuklear.h:3420
nk_window_has_focus
NK_API int nk_window_has_focus(const struct nk_context *)
nk_style::button
struct nk_style_button button
Definition: nuklear.h:5221
nk_style_edit::cursor_size
float cursor_size
Definition: nuklear.h:5044
nk_command_arc_filled::cx
short cx
Definition: nuklear.h:4499
nk_rectiv
NK_API struct nk_rect nk_rectiv(const int *xywh)
NK_LAYOUT_DYNAMIC
@ NK_LAYOUT_DYNAMIC
Definition: nuklear.h:5289
nk_color_hsv_i
NK_API void nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color)
NK_INTERSECT
#define NK_INTERSECT(x0, y0, w0, h0, x1, y1, w1, h1)
Definition: nuklear.h:5625
NK_TREE_NODE
@ NK_TREE_NODE
Definition: nuklear.h:481
NK_WIDGET_STATE_HOVER
@ NK_WIDGET_STATE_HOVER
Definition: nuklear.h:3051
nk_end
NK_API void nk_end(struct nk_context *ctx)
NK_CONTAINER_OF
#define NK_CONTAINER_OF(ptr, type, member)
Definition: nuklear.h:5663
nk_clipboard::copy
nk_plugin_copy copy
Definition: nuklear.h:4251
NK_STATIC
@ NK_STATIC
Definition: nuklear.h:480
nk_keyboard::keys
struct nk_key keys[NK_KEY_MAX]
Definition: nuklear.h:4621
NK_KEY_SCROLL_END
@ NK_KEY_SCROLL_END
Definition: nuklear.h:766
nk_style_selectable::padding
struct nk_vec2 padding
Definition: nuklear.h:4908
NK_STYLE_ITEM_COLOR
@ NK_STYLE_ITEM_COLOR
Definition: nuklear.h:4807
nk_property_state::select_start
int select_start
Definition: nuklear.h:5401
NK_TEXT_EDIT_MODE_VIEW
@ NK_TEXT_EDIT_MODE_VIEW
Definition: nuklear.h:4276
nk_command_rect_filled
Definition: nuklear.h:4438
nk_command_triangle::b
struct nk_vec2i b
Definition: nuklear.h:4460
nk_text_edit_mode
nk_text_edit_mode
Definition: nuklear.h:4275
nk_list_view::end
int end
Definition: nuklear.h:3028
NK_KEY_SCROLL_UP
@ NK_KEY_SCROLL_UP
Definition: nuklear.h:768
nk_fill_polygon
NK_API void nk_fill_polygon(struct nk_command_buffer *, float *, int point_count, struct nk_color)
nk_style_pop_style_item
NK_API int nk_style_pop_style_item(struct nk_context *)
nk_style_colors
nk_style_colors
Definition: nuklear.h:3562
nk_pool::alloc
struct nk_allocator alloc
Definition: nuklear.h:5560
NK_COMMAND_SCISSOR
@ NK_COMMAND_SCISSOR
Definition: nuklear.h:4377
nk_style_window_header::padding
struct nk_vec2 padding
Definition: nuklear.h:5171
nk_style_edit::selected_text_normal
struct nk_color selected_text_normal
Definition: nuklear.h:5038
NK_VERTICAL
@ NK_VERTICAL
Definition: nuklear.h:473
nk_style_combo::symbol_normal
struct nk_color symbol_normal
Definition: nuklear.h:5107
nk_style_toggle::text_normal
struct nk_color text_normal
Definition: nuklear.h:4865
nk_style_window::header
struct nk_style_window_header header
Definition: nuklear.h:5177
nk_contextual_item_image_label
NK_API int nk_contextual_item_image_label(struct nk_context *, struct nk_image, const char *, nk_flags alignment)
nk_combobox_string
NK_API void nk_combobox_string(struct nk_context *, const char *items_separated_by_zeros, int *selected, int count, int item_height, struct nk_vec2 size)
NK_SYMBOL_CIRCLE_OUTLINE
@ NK_SYMBOL_CIRCLE_OUTLINE
Definition: nuklear.h:499
nk_layout_row_push
NK_API void nk_layout_row_push(struct nk_context *, float value)
nk_ushort
NK_UINT16 nk_ushort
Definition: nuklear.h:403
nk_style_slider::show_buttons
int show_buttons
Definition: nuklear.h:4945
NK_PANEL_SET_POPUP
@ NK_PANEL_SET_POPUP
Definition: nuklear.h:5265
nk_command_arc_filled::color
struct nk_color color
Definition: nuklear.h:4502
NK_COMMAND_POLYLINE
@ NK_COMMAND_POLYLINE
Definition: nuklear.h:4391
nk_chart::y
float y
Definition: nuklear.h:5281
nk_style_progress::cursor_active
struct nk_style_item cursor_active
Definition: nuklear.h:4967
nk_style::cursor_last
struct nk_cursor * cursor_last
Definition: nuklear.h:5217
nk_panel::has_scrolling
unsigned int has_scrolling
Definition: nuklear.h:5336
nk_buffer_total
NK_API nk_size nk_buffer_total(struct nk_buffer *)
nk_style_scrollbar::userdata
nk_handle userdata
Definition: nuklear.h:5011
nk_menu_begin_text
NK_API int nk_menu_begin_text(struct nk_context *, const char *title, int title_len, nk_flags align, struct nk_vec2 size)
nk_style_slider::padding
struct nk_vec2 padding
Definition: nuklear.h:4940
nk_style_window::group_border_color
struct nk_color group_border_color
Definition: nuklear.h:5186
nk_style_scrollbar::inc_button
struct nk_style_button inc_button
Definition: nuklear.h:5005
NK_CONVERT_INVALID_PARAM
@ NK_CONVERT_INVALID_PARAM
Definition: nuklear.h:1146
NK_PTR_TO_UINT
#define NK_PTR_TO_UINT(x)
Definition: nuklear.h:5648
NK_KEY_SCROLL_START
@ NK_KEY_SCROLL_START
Definition: nuklear.h:765
nk_text_alignment
nk_text_alignment
Definition: nuklear.h:3081
nk_scroll
Definition: nuklear.h:468
NK_LAYOUT_DYNAMIC_FREE
@ NK_LAYOUT_DYNAMIC_FREE
Definition: nuklear.h:5288
nk_vec2i
NK_API struct nk_vec2 nk_vec2i(int x, int y)
nk_style_toggle::active
struct nk_style_item active
Definition: nuklear.h:4857
NK_COLOR_CHART
@ NK_COLOR_CHART
Definition: nuklear.h:3583
nk_buffer::pool
struct nk_allocator pool
Definition: nuklear.h:4122
NK_BUTTON_LEFT
@ NK_BUTTON_LEFT
Definition: nuklear.h:772
nk_button_image_text
NK_API int nk_button_image_text(struct nk_context *, struct nk_image img, const char *, int, nk_flags alignment)
nk_select_image_label
NK_API int nk_select_image_label(struct nk_context *, struct nk_image, const char *, nk_flags align, int value)
NK_KEY_SCROLL_DOWN
@ NK_KEY_SCROLL_DOWN
Definition: nuklear.h:767
nk_command_line::begin
struct nk_vec2i begin
Definition: nuklear.h:4415
nk_row_layout::item
struct nk_rect item
Definition: nuklear.h:5308
nk_filter_hex
NK_API int nk_filter_hex(const struct nk_text_edit *, nk_rune unicode)
nk_window_get_content_region
NK_API struct nk_rect nk_window_get_content_region(struct nk_context *)
nk_window::scrollbar
struct nk_scroll scrollbar
Definition: nuklear.h:5416
NK_LAYOUT_STATIC
@ NK_LAYOUT_STATIC
Definition: nuklear.h:5293
NK_KEY_ENTER
@ NK_KEY_ENTER
Definition: nuklear.h:741
nk_style_edit::hover
struct nk_style_item hover
Definition: nuklear.h:5019
nk_utf_decode
NK_API int nk_utf_decode(const char *, nk_rune *, int)
NK_LAYOUT_DYNAMIC_FIXED
@ NK_LAYOUT_DYNAMIC_FIXED
Definition: nuklear.h:5286
nk_buffer_allocation_type
nk_buffer_allocation_type
Definition: nuklear.h:4107
nk_layout_space_begin
NK_API void nk_layout_space_begin(struct nk_context *, enum nk_layout_format, float height, int widget_count)
nk_style_pop_flags
NK_API int nk_style_pop_flags(struct nk_context *)
nk_image_color
NK_API void nk_image_color(struct nk_context *, struct nk_image, struct nk_color)
nk_widget_states
nk_widget_states
Definition: nuklear.h:3047
nk_str_insert_at_char
NK_API int nk_str_insert_at_char(struct nk_str *, int pos, const char *, int)
NK_KEY_TEXT_LINE_END
@ NK_KEY_TEXT_LINE_END
Definition: nuklear.h:756
nk_command_image
Definition: nuklear.h:4528
nk_menu_begin_image_label
NK_API int nk_menu_begin_image_label(struct nk_context *, const char *, nk_flags align, struct nk_image, struct nk_vec2 size)
nk_style_slider::cursor_active
struct nk_style_item cursor_active
Definition: nuklear.h:4934
nk_property_state::length
int length
Definition: nuklear.h:5399
nk_str_init
NK_API void nk_str_init(struct nk_str *, const struct nk_allocator *, nk_size size)
nk_button_symbol_label_styled
NK_API int nk_button_symbol_label_styled(struct nk_context *ctx, const struct nk_style_button *style, enum nk_symbol_type symbol, const char *title, nk_flags align)
nk_str_append_str_utf8
NK_API int nk_str_append_str_utf8(struct nk_str *, const char *)
nk_query_font_glyph_f
void(* nk_query_font_glyph_f)(nk_handle handle, float font_height, struct nk_user_font_glyph *glyph, nk_rune codepoint, nk_rune next_codepoint)
Definition: nuklear.h:3898
nk_command_arc::a
float a[2]
Definition: nuklear.h:4493
nk_rgb_hex
NK_API struct nk_color nk_rgb_hex(const char *rgb)
nk_chart_slot::index
int index
Definition: nuklear.h:5276
NK_COMMAND_IMAGE
@ NK_COMMAND_IMAGE
Definition: nuklear.h:4393
NK_WINDOW_CLOSABLE
@ NK_WINDOW_CLOSABLE
Definition: nuklear.h:1455
nk_style_window_header::spacing
struct nk_vec2 spacing
Definition: nuklear.h:5173
NK_STORAGE
#define NK_STORAGE
Definition: nuklear.h:274
NK_PANEL_SET_NONBLOCK
@ NK_PANEL_SET_NONBLOCK
Definition: nuklear.h:5264
nk_context::count
unsigned int count
Definition: nuklear.h:5607
nk_style::chart
struct nk_style_chart chart
Definition: nuklear.h:5231
nk_text_edit::padding1
unsigned char padding1
Definition: nuklear.h:4296
nk_command_triangle_filled::a
struct nk_vec2i a
Definition: nuklear.h:4467
nk_command_rect_multi_color::top
struct nk_color top
Definition: nuklear.h:4451
nk_style_slider::bar_filled
struct nk_color bar_filled
Definition: nuklear.h:4929
nk_handle
Definition: nuklear.h:465
nk_text_undo_record::char_storage
short char_storage
Definition: nuklear.h:4258
nk_style_chart
Definition: nuklear.h:5081
nk_input_is_mouse_click_down_in_rect
NK_API int nk_input_is_mouse_click_down_in_rect(const struct nk_input *i, enum nk_buttons id, struct nk_rect b, int down)
nk_command_text::header
struct nk_command header
Definition: nuklear.h:4547
nk_menu_state::h
float h
Definition: nuklear.h:5322
nk_window_get_canvas
NK_API struct nk_command_buffer * nk_window_get_canvas(struct nk_context *)
nk_list_view::ctx
struct nk_context * ctx
Definition: nuklear.h:3031
nk_edit_state::mode
unsigned char mode
Definition: nuklear.h:5392
nk_window_is_closed
NK_API int nk_window_is_closed(struct nk_context *, const char *)
nk_style_selectable::pressed
struct nk_style_item pressed
Definition: nuklear.h:4887
nk_label_colored
NK_API void nk_label_colored(struct nk_context *, const char *, nk_flags align, struct nk_color)
nk_command_curve
Definition: nuklear.h:4420
nk_combo_item_image_text
NK_API int nk_combo_item_image_text(struct nk_context *, struct nk_image, const char *, int, nk_flags alignment)
nk_colorf_hsva_fv
NK_API void nk_colorf_hsva_fv(float *hsva, struct nk_colorf in)
nk_color_dv
NK_API void nk_color_dv(double *rgba_out, struct nk_color)
nk_context::overlay
struct nk_command_buffer overlay
Definition: nuklear.h:5596
nk_checkbox_text
NK_API int nk_checkbox_text(struct nk_context *, const char *, int, int *active)
NK_KEY_SHIFT
@ NK_KEY_SHIFT
Definition: nuklear.h:738
nk_buffer::allocated
nk_size allocated
Definition: nuklear.h:4130
nk_subimage_id
NK_API struct nk_image nk_subimage_id(int, unsigned short w, unsigned short h, struct nk_rect sub_region)
nk_window::layout
struct nk_panel * layout
Definition: nuklear.h:5418
nk_menu_item_image_text
NK_API int nk_menu_item_image_text(struct nk_context *, struct nk_image, const char *, int len, nk_flags alignment)
nk_style_window::popup_border_color
struct nk_color popup_border_color
Definition: nuklear.h:5182
nk_style_edit::border_color
struct nk_color border_color
Definition: nuklear.h:5021
nk_recti::w
short w
Definition: nuklear.h:463
nk_rect::h
float h
Definition: nuklear.h:462
nk_style_toggle::text_background
struct nk_color text_background
Definition: nuklear.h:4868
nk_command_text::height
float height
Definition: nuklear.h:4553
nk_selectable_image_label
NK_API int nk_selectable_image_label(struct nk_context *, struct nk_image, const char *, nk_flags align, int *value)
NK_TEXT_EDIT_MULTI_LINE
@ NK_TEXT_EDIT_MULTI_LINE
Definition: nuklear.h:4272
NK_BUTTON_RIGHT
@ NK_BUTTON_RIGHT
Definition: nuklear.h:774
NK_SYMBOL_UNDERSCORE
@ NK_SYMBOL_UNDERSCORE
Definition: nuklear.h:497
NK_COLOR_EDIT
@ NK_COLOR_EDIT
Definition: nuklear.h:3580
nk_command_polyline
Definition: nuklear.h:4520
nk_tooltip_begin
NK_API int nk_tooltip_begin(struct nk_context *, float width)
nk_style_tab::tab_maximize_button
struct nk_style_button tab_maximize_button
Definition: nuklear.h:5132
nk_row_layout::ratio
const float * ratio
Definition: nuklear.h:5303
nk_str_rune_at
NK_API nk_rune nk_str_rune_at(const struct nk_str *, int pos)
nk_panel::parent
struct nk_panel * parent
Definition: nuklear.h:5342
nk_textedit_redo
NK_API void nk_textedit_redo(struct nk_text_edit *)
nk_murmur_hash
NK_API nk_hash nk_murmur_hash(const void *key, int len, nk_hash seed)
NK_LAYOUT_COUNT
@ NK_LAYOUT_COUNT
Definition: nuklear.h:5295
NK_COLOR_SCROLLBAR_CURSOR_ACTIVE
@ NK_COLOR_SCROLLBAR_CURSOR_ACTIVE
Definition: nuklear.h:3589
NK_HEADER_LEFT
@ NK_HEADER_LEFT
Definition: nuklear.h:5148
nk_colorf_hsva_f
NK_API void nk_colorf_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_colorf in)
nk_zero_struct
#define nk_zero_struct(s)
Definition: nuklear.h:5637
nk_style::scrollh
struct nk_style_scrollbar scrollh
Definition: nuklear.h:5232
nk_check_label
NK_API int nk_check_label(struct nk_context *, const char *, int active)
NK_KEY_RIGHT
@ NK_KEY_RIGHT
Definition: nuklear.h:750
nk_pool
Definition: nuklear.h:5559
nk_rgba_cf
NK_API struct nk_color nk_rgba_cf(struct nk_colorf c)
nk_layout_row_template_push_variable
NK_API void nk_layout_row_template_push_variable(struct nk_context *, float min_width)
nk_layout_format
nk_layout_format
Definition: nuklear.h:480
nk_panel::footer_height
float footer_height
Definition: nuklear.h:5333
nk_command_scissor
Definition: nuklear.h:4406
NK_FLAGS_STACK_SIZE
#define NK_FLAGS_STACK_SIZE
Definition: nuklear.h:5482
nk_edit_unfocus
NK_API void nk_edit_unfocus(struct nk_context *)
nk_window::name
nk_hash name
Definition: nuklear.h:5411
nk_style_button::border
float border
Definition: nuklear.h:4841
nk_combo_begin_symbol_text
NK_API int nk_combo_begin_symbol_text(struct nk_context *, const char *selected, int, enum nk_symbol_type, struct nk_vec2 size)
nk_style_set_font
NK_API void nk_style_set_font(struct nk_context *, const struct nk_user_font *)
nk_popup_state::type
enum nk_panel_type type
Definition: nuklear.h:5373
nk_color_d
NK_API void nk_color_d(double *r, double *g, double *b, double *a, struct nk_color)
nk_style_edit::border
float border
Definition: nuklear.h:5042
nk_scroll::x
nk_uint x
Definition: nuklear.h:468
NK_RIGHT
@ NK_RIGHT
Definition: nuklear.h:470
nk_command_buffer::clip
struct nk_rect clip
Definition: nuklear.h:4565
nk_style_property::label_hover
struct nk_color label_hover
Definition: nuklear.h:5059
nk_context::last_widget_state
nk_flags last_widget_state
Definition: nuklear.h:5576
nk_window_get_content_region_max
NK_API struct nk_vec2 nk_window_get_content_region_max(struct nk_context *)
nk_input_char
NK_API void nk_input_char(struct nk_context *, char)
NK_PANEL_COMBO
@ NK_PANEL_COMBO
Definition: nuklear.h:5259
nk_color_hsv_b
NK_API void nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color)
NK_KEY_MAX
@ NK_KEY_MAX
Definition: nuklear.h:769
nk_style_pop_color
NK_API int nk_style_pop_color(struct nk_context *)
nk_list_view::total_height
int total_height
Definition: nuklear.h:3030
nk_panel::offset_x
nk_uint * offset_x
Definition: nuklear.h:5330
nk_command_rect
Definition: nuklear.h:4429
nk_style_property::active
struct nk_style_item active
Definition: nuklear.h:5054
NK_BUTTON_MAX
@ NK_BUTTON_MAX
Definition: nuklear.h:776
nk_chart_end
NK_API void nk_chart_end(struct nk_context *)
nk_style_combo::content_padding
struct nk_vec2 content_padding
Definition: nuklear.h:5120
nk_menu_item_symbol_text
NK_API int nk_menu_item_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags alignment)
nk_show_states
nk_show_states
Definition: nuklear.h:475
nk_tree_state_image_push
NK_API int nk_tree_state_image_push(struct nk_context *, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states *state)
nk_layout_row_template_push_static
NK_API void nk_layout_row_template_push_static(struct nk_context *, float width)
NK_COLOR_TOGGLE_CURSOR
@ NK_COLOR_TOGGLE_CURSOR
Definition: nuklear.h:3572
NK_COLOR_STACK_SIZE
#define NK_COLOR_STACK_SIZE
Definition: nuklear.h:5486
nk_combo_begin_symbol_label
NK_API int nk_combo_begin_symbol_label(struct nk_context *, const char *selected, enum nk_symbol_type, struct nk_vec2 size)
nk_vec2::x
float x
Definition: nuklear.h:460
nk_widget_size
NK_API struct nk_vec2 nk_widget_size(struct nk_context *)
nk_colorf::a
float a
Definition: nuklear.h:459
nk_row_layout::tree_depth
int tree_depth
Definition: nuklear.h:5309
nk_style::tab
struct nk_style_tab tab
Definition: nuklear.h:5234
nk_rgba_iv
NK_API struct nk_color nk_rgba_iv(const int *rgba)
nk_chart_push
NK_API nk_flags nk_chart_push(struct nk_context *, float)
nk_command_text::x
short x
Definition: nuklear.h:4551
nk_style::slider
struct nk_style_slider slider
Definition: nuklear.h:5227
nk_buffer::grow_factor
float grow_factor
Definition: nuklear.h:4128
NK_TEXT_LEFT
@ NK_TEXT_LEFT
Definition: nuklear.h:3082
nk_style_tab::indent
float indent
Definition: nuklear.h:5142
nk_style_window::combo_border
float combo_border
Definition: nuklear.h:5191
nk_menu_item_symbol_label
NK_API int nk_menu_item_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags alignment)
nk_edit_state::single_line
unsigned char single_line
Definition: nuklear.h:5393
NK_EDIT_SIMPLE
@ NK_EDIT_SIMPLE
Definition: nuklear.h:3432
nk_check_flags_label
NK_API unsigned nk_check_flags_label(struct nk_context *, const char *, unsigned int flags, unsigned int value)
nk_context::stacks
struct nk_configuration_stacks stacks
Definition: nuklear.h:5578
nk_edit_state::active
int active
Definition: nuklear.h:5387
nk_style_tab::sym_maximize
enum nk_symbol_type sym_maximize
Definition: nuklear.h:5137
NK_UNUSED
#define NK_UNUSED(x)
Definition: nuklear.h:5618
nk_style_chart::border
float border
Definition: nuklear.h:5089
nk_command_circle::header
struct nk_command header
Definition: nuklear.h:4474
nk_input_mouse_clicked
NK_API int nk_input_mouse_clicked(const struct nk_input *, enum nk_buttons, struct nk_rect)
nk_str_insert_str_char
NK_API int nk_str_insert_str_char(struct nk_str *, int pos, const char *)
nk_style_window_header::label_active
struct nk_color label_active
Definition: nuklear.h:5167
nk_command_polyline::points
struct nk_vec2i points[1]
Definition: nuklear.h:4525
nk_button_label
NK_API int nk_button_label(struct nk_context *, const char *title)
nk_memory_status::allocated
nk_size allocated
Definition: nuklear.h:4097
nk_window::scrolled
unsigned int scrolled
Definition: nuklear.h:5425
nk_command_text::length
int length
Definition: nuklear.h:4554
nk_window_get_content_region_size
NK_API struct nk_vec2 nk_window_get_content_region_size(struct nk_context *)
nk_row_layout::item_offset
float item_offset
Definition: nuklear.h:5306
nk_edit_focus
NK_API void nk_edit_focus(struct nk_context *, nk_flags flags)
NK_MAX
#define NK_MAX(a, b)
Definition: nuklear.h:303
nk_get_null_rect
NK_API struct nk_rect nk_get_null_rect(void)
nk_command_rect::color
struct nk_color color
Definition: nuklear.h:4435
nk_style_combo::label_active
struct nk_color label_active
Definition: nuklear.h:5104
NK_PANEL_SET_SUB
@ NK_PANEL_SET_SUB
Definition: nuklear.h:5266
nk_style_progress::border_color
struct nk_color border_color
Definition: nuklear.h:4962
nk_style_tab::border_color
struct nk_color border_color
Definition: nuklear.h:5128
nk_buttons
nk_buttons
Definition: nuklear.h:771
nk_style_tab::node_minimize_button
struct nk_style_button node_minimize_button
Definition: nuklear.h:5135
nk_style_window::min_size
struct nk_vec2 min_size
Definition: nuklear.h:5202
nk_list_view
Definition: nuklear.h:3026
nk_style_scrollbar::draw_end
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:5013
nk_check_text
NK_API int nk_check_text(struct nk_context *, const char *, int, int active)
nk_command_arc::cy
short cy
Definition: nuklear.h:4490
NK_WIDGET_STATE_INACTIVE
@ NK_WIDGET_STATE_INACTIVE
Definition: nuklear.h:3049
nk_command_image::header
struct nk_command header
Definition: nuklear.h:4529
NK_EDIT_ACTIVE
@ NK_EDIT_ACTIVE
Definition: nuklear.h:3438
nk_style_scrollbar::border_cursor
float border_cursor
Definition: nuklear.h:4999
nk_str_remove_chars
NK_API void nk_str_remove_chars(struct nk_str *, int len)
NK_HORIZONTAL
@ NK_HORIZONTAL
Definition: nuklear.h:473
nk_style_selectable::text_normal_active
struct nk_color text_normal_active
Definition: nuklear.h:4900
nk_hsva_f
NK_API struct nk_color nk_hsva_f(float h, float s, float v, float a)
nk_mouse::ungrab
unsigned char ungrab
Definition: nuklear.h:4613
nk_command_rect_filled::rounding
unsigned short rounding
Definition: nuklear.h:4440
nk_style_item_image
NK_API struct nk_style_item nk_style_item_image(struct nk_image img)
NK_FIXED
@ NK_FIXED
Definition: nuklear.h:472
nk_command_curve::ctrl
struct nk_vec2i ctrl[2]
Definition: nuklear.h:4425
nk_style_scrollbar::cursor_hover
struct nk_style_item cursor_hover
Definition: nuklear.h:4992
NK_EDIT_FIELD
@ NK_EDIT_FIELD
Definition: nuklear.h:3433
nk_filter_default
NK_API int nk_filter_default(const struct nk_text_edit *, nk_rune unicode)
nk_color_hsva_f
NK_API void nk_color_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_color)
NK_EDIT_AUTO_SELECT
@ NK_EDIT_AUTO_SELECT
Definition: nuklear.h:3419
nk_command_circle_filled::color
struct nk_color color
Definition: nuklear.h:4485
NK_COMMAND_ARC_FILLED
@ NK_COMMAND_ARC_FILLED
Definition: nuklear.h:4386
NK_WINDOW_NO_INPUT
@ NK_WINDOW_NO_INPUT
Definition: nuklear.h:1462